55#include < cstdio> // For popen and fgets
66#include < memory> // For std::unique_ptr
77#include < regex> // For std::regex
8+ #include < boost/filesystem.hpp>
89
910namespace am
1011{
@@ -182,7 +183,26 @@ void ResourceStatus::updateInfos()
182183
183184 cpu_infos_old_ = cpu_infos_;
184185
185- getGPUInfo (gpu_infos_);
186+ gpu_info_ = getGPUInfo ();
187+ stats_->gpu_stats = 50 ;
188+ ROS_INFO (" GPU Load Percent: %d , Temp: %d" , gpu_info_.load_percent , gpu_info_.temp );
189+ if (gpu_info_.load_percent > 90 )
190+ {
191+ stats_->gpu_stats = 100 ;
192+ ROS_ERROR (" GPU Issues: LOAD Percent: %d, Temp: %d" , gpu_info_.load_percent , gpu_info_.temp );
193+ }
194+
195+
196+ // check the drive stats
197+ stats_->drive_stats = 50 ;
198+ am::DiskInfo disk_info = getDiskInfo ();
199+ if (disk_info.percentUsed > 98.0 )
200+ {
201+ stats_->drive_stats = 100 ;
202+ int coef = 1024 *1024 ;
203+ ROS_ERROR (" Disk total: %lld MB, available: %lld MB, used: %lld MB, percentage: %f" , (disk_info.totalSpace /coef), (disk_info.availableSpace /coef), (disk_info.usedSpace /coef), disk_info.percentUsed );
204+ }
205+
186206}
187207
188208
@@ -224,21 +244,69 @@ am::MemoryInfo& ResourceStatus::getMemoryInfo()
224244 return mi;
225245}
226246
227- void ResourceStatus::getGPUInfo (std::vector<am::GpuInfo> &gpu_infos)
247+ // Function to read the content of a file
248+ std::string ResourceStatus::readFile (const std::string& path)
228249{
229- gpu_infos.clear ();
250+ std::ifstream file (path);
251+ if (!file.is_open ()) {
252+ throw std::runtime_error (" Error: Unable to open file " + path);
253+ }
254+
255+ std::string content;
256+ std::getline (file, content);
257+ file.close ();
258+ return content;
259+ }
260+
261+ am::GpuInfo ResourceStatus::getGPUInfo ()
262+ {
263+ am::GpuInfo gpu_info;
264+
265+ // "/sys/devices/gpu.0/load" exists only in Jetpack
266+ // in contrast, nvidia-smi only exists in amd64 architure
267+ const std::string loadPath = " /sys/devices/gpu.0/load" ;
268+ if (boost::filesystem::exists (loadPath))
269+ {
270+ std::string loadStr = readFile (loadPath);
271+ gpu_info.load_percent = std::stoi (loadStr) / 1000 ; // Convert to percentage
272+
273+ const std::string baseThermalPath = " /sys/class/thermal/" ;
274+ const std::string typeSuffix = " /type" ;
275+ const std::string tempSuffix = " /temp" ;
276+
277+ for (int i = 0 ; i < 10 ; ++i) { // Check up to 10 thermal zones
278+ try {
279+ std::string typePath = baseThermalPath + " thermal_zone" + std::to_string (i) + typeSuffix;
280+ std::string type = readFile (typePath);
281+ if (type.find (" GPU" ) != std::string::npos)
282+ { // Look for the GPU thermal zone
283+ std::string tempPath = baseThermalPath + " thermal_zone" + std::to_string (i) + tempSuffix;
284+ std::string tempStr = readFile (tempPath);
285+ gpu_info.temp = std::stoi (tempStr) / 1000 ; // Convert millidegrees to degrees Celsius
286+ }
287+ } catch (...) {
288+ // Ignore errors and continue checking other zones
289+ }
290+ }
291+ throw std::runtime_error (" Error: GPU thermal zone not found." );
292+
293+ return gpu_info;
294+ }
295+
296+
230297 // Execute the nvidia-smi command and read the output directly
231298 const std::string command = " nvidia-smi --query-gpu=name,utilization.gpu,temperature.gpu,memory.used,memory.free --format=csv,nounits,noheader" ;
232299 FILE* pipe = popen (command.c_str (), " r" );
233300 if (!pipe)
234301 {
235302 ROS_ERROR (" Error: Unable to execute nvidia-smi. Ensure it's installed and available in PATH." );
236- return ;
303+ return gpu_info ;
237304 }
238305
239306 char buffer[128 ];
240307 std::ostringstream result;
241- while (fgets (buffer, sizeof (buffer), pipe) != nullptr ) {
308+ while (fgets (buffer, sizeof (buffer), pipe) != nullptr )
309+ {
242310 result << buffer;
243311 }
244312 pclose (pipe);
@@ -248,10 +316,8 @@ void ResourceStatus::getGPUInfo(std::vector<am::GpuInfo> &gpu_infos)
248316 std::string line;
249317 while (std::getline (iss, line))
250318 {
251-
252319 // ROS_INFO(GREEN "%s" COLOR_RESET, line.c_str());
253320 std::istringstream lineStream (line);
254- am::GpuInfo gpu_info;
255321 // Parse memory used and free values
256322 std::string gpuName;
257323 int gpuUtilization, gpuTemperature, memoryUsed, memoryFree;
@@ -269,14 +335,15 @@ void ResourceStatus::getGPUInfo(std::vector<am::GpuInfo> &gpu_infos)
269335 lineStream >> memoryFree;
270336
271337 gpu_info.gpu_name = gpuName;
272- gpu_info.util_percent = gpuUtilization;
338+ gpu_info.load_percent = gpuUtilization;
273339 gpu_info.temp = gpuTemperature;
274- gpu_info.mem_free = memoryFree;
275- gpu_info.mem_used = memoryUsed;
276- stats_->gpu_stats = (gpu_info.util_percent >90 ?100 :50 );
277-
278- gpu_infos.push_back (gpu_info);
340+
341+ return gpu_info;
279342 }
343+
344+
345+
346+ return gpu_info;
280347}
281348
282349
@@ -385,10 +452,7 @@ void ResourceStatus::print()
385452 ROS_INFO (" UpTime: %f" , uptime_seconds_);
386453
387454 msg = " " ;
388- for (int i = 0 ; i < gpu_infos_.size (); i++)
389- {
390- msg += gpu_infos_[i].gpu_name + " : Temp[C] = " + std::to_string (gpu_infos_[i].temp ) + " , Used[%]: " + std::to_string (gpu_infos_[i].util_percent );
391- }
455+ msg += " GPU: Temp[C] = " + std::to_string (gpu_info_.temp ) + " , Used[%]: " + std::to_string (gpu_info_.load_percent );
392456
393457 ROS_INFO (" %s" , msg.c_str ());
394458}
@@ -567,6 +631,25 @@ std::vector<std::string> ResourceStatus::getInetAddresses()
567631 return inetAddresses;
568632}
569633
634+
635+ // Function to get disk usage information
636+ DiskInfo ResourceStatus::getDiskInfo (const std::string& path)
637+ {
638+ struct statvfs stat;
639+
640+ if (statvfs (path.c_str (), &stat) != 0 ) {
641+ throw std::runtime_error (" Error: Unable to get disk information for " + path);
642+ }
643+
644+ DiskInfo info;
645+ info.totalSpace = stat.f_blocks * stat.f_frsize ; // Total blocks * block size
646+ info.availableSpace = stat.f_bavail * stat.f_frsize ; // Available blocks * block size
647+ info.usedSpace = info.totalSpace - info.availableSpace ;
648+ info.percentUsed = (info.usedSpace * 100.0 ) / info.totalSpace ;
649+
650+ return info;
651+ }
652+
570653/*
571654 Timer Callback: this is where everything is updated
572655 */
0 commit comments