Carma-platform v4.2.0
CARMA Platform is built on robot operating system (ROS) and utilizes open source software (OSS) that enables Cooperative Driving Automation (CDA) features to allow Automated Driving Systems to interact and cooperate with infrastructure and other vehicles through communication.
monitor-ros-cpu Namespace Reference

Functions

def parse_args ()
 
def setup_logging_directory (output_dir)
 
def is_ros_related_process (proc_info, cmdline)
 
def get_process_environment (pid)
 
def main ()
 

Variables

dictionary ROS_KEYWORDS
 
dictionary EXCLUDE_KEYWORDS = {"code", "chrome", "firefox", "vscode", "gnome"}
 

Function Documentation

◆ get_process_environment()

def monitor-ros-cpu.get_process_environment (   pid)
Try to get ROS-related environment variables for a process

Definition at line 82 of file monitor-ros-cpu.py.

83 """
84 Try to get ROS-related environment variables for a process
85 """
86 try:
87 proc = psutil.Process(pid)
88 env = proc.environ()
89 ros_env = {k: v for k, v in env.items() if "ROS" in k}
90 return bool(ros_env)
91 except (psutil.NoSuchProcess, psutil.AccessDenied):
92 return False
93
94
def get_process_environment(pid)

◆ is_ros_related_process()

def monitor-ros-cpu.is_ros_related_process (   proc_info,
  cmdline 
)
Check if a process is ROS-related based on name and command line

Definition at line 64 of file monitor-ros-cpu.py.

64def is_ros_related_process(proc_info, cmdline):
65 """
66 Check if a process is ROS-related based on name and command line
67 """
68 # Convert process information to lowercase for case-insensitive matching
69 name_lower = proc_info["name"].lower()
70 cmdline_lower = cmdline.lower()
71
72 # Check exclusions first
73 if any(excl in name_lower or excl in cmdline_lower for excl in EXCLUDE_KEYWORDS):
74 return False
75
76 # Check for ROS-related keywords in process name and command line
77 return any(
78 keyword in name_lower or keyword in cmdline_lower for keyword in ROS_KEYWORDS
79 )
80
81
def is_ros_related_process(proc_info, cmdline)

Referenced by main().

Here is the caller graph for this function:

◆ main()

def monitor-ros-cpu.main ( )

Definition at line 95 of file monitor-ros-cpu.py.

95def main():
96 args = parse_args()
97
98 # Add any additional include patterns from command line
99 if args.include_pattern:
100 additional_patterns = set(args.include_pattern.split(","))
101 ROS_KEYWORDS.update(additional_patterns)
102
103 output_file = setup_logging_directory(args.output_dir)
104
105 with open(output_file, mode="a") as file:
106 writer = csv.writer(file)
107 writer.writerow(
108 [
109 "Timestamp",
110 "PID",
111 "Process Name",
112 "CPU (%)",
113 "Memory (%)",
114 "Command Line",
115 "Total CPU (%)",
116 "Total CPU Num",
117 "Total Memory (%)",
118 "Total Memory (GB)",
119 ]
120 )
121
122 print(f"Starting to monitor the CPU usage data and saving to: {output_file}")
123
124 # Total CPU and memory size in GB doesn't change
125 total_memory_gb = psutil.virtual_memory().total / (1024**3)
126 total_cpus = os.cpu_count()
127
128 while True:
129 timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
130 total_cpu_percent = psutil.cpu_percent(interval=None)
131 total_memory_percent = (
132 psutil.virtual_memory().percent
133 ) # Get total memory usage
134
135 for proc in psutil.process_iter(
136 ["pid", "name", "cpu_percent", "memory_percent", "cmdline"]
137 ):
138 try:
139 cmdline = (
140 " ".join(proc.info["cmdline"]) if proc.info["cmdline"] else ""
141 )
142
143 if is_ros_related_process(proc.info, cmdline):
144 pid = proc.info["pid"]
145 name = proc.info["name"]
146 cpu_percent = proc.info["cpu_percent"]
147 memory_percent = proc.info["memory_percent"]
148
149 writer.writerow(
150 [
151 timestamp,
152 pid,
153 name,
154 cpu_percent,
155 memory_percent,
156 cmdline,
157 total_cpu_percent,
158 total_cpus,
159 total_memory_percent,
160 total_memory_gb,
161 ]
162 )
163
164 except (
165 psutil.NoSuchProcess,
166 psutil.AccessDenied,
167 psutil.ZombieProcess,
168 ):
169 continue
170
171 time.sleep(1)
172
173
def setup_logging_directory(output_dir)

References is_ros_related_process(), main(), parse_args(), and setup_logging_directory().

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_args()

def monitor-ros-cpu.parse_args ( )

Definition at line 40 of file monitor-ros-cpu.py.

40def parse_args():
41 parser = argparse.ArgumentParser(description="Monitor CPU usage of ROS2 nodes")
42 parser.add_argument(
43 "--output-dir",
44 "-o",
45 default="carma-cpu-usage-logs",
46 help="Directory to store output files (default: carma-cpu-usage-logs)",
47 )
48 parser.add_argument(
49 "--include-pattern",
50 "-i",
51 help="Additional comma-separated patterns to include in process filtering",
52 )
53 return parser.parse_args()
54
55

Referenced by main().

Here is the caller graph for this function:

◆ setup_logging_directory()

def monitor-ros-cpu.setup_logging_directory (   output_dir)

Definition at line 56 of file monitor-ros-cpu.py.

56def setup_logging_directory(output_dir):
57 if not os.path.exists(output_dir):
58 os.makedirs(output_dir)
59 timestamp = datetime.now().strftime("%Y_%m_%d-%H_%M_%S")
60 filename = f"cpu_usage_ros2_nodes_{timestamp}.csv"
61 return os.path.join(output_dir, filename)
62
63

Referenced by main().

Here is the caller graph for this function:

Variable Documentation

◆ EXCLUDE_KEYWORDS

dictionary monitor-ros-cpu.EXCLUDE_KEYWORDS = {"code", "chrome", "firefox", "vscode", "gnome"}

Definition at line 37 of file monitor-ros-cpu.py.

◆ ROS_KEYWORDS

dictionary monitor-ros-cpu.ROS_KEYWORDS
Initial value:
1= {
2 "ros",
3 "node",
4 "rviz",
5 "rqt",
6 "/opt/ros/", # ROS installation path
7 "/opt/carma/", # CARMA ROS installation path
8 "roscore",
9 "rosmaster",
10 "roslaunch",
11 "rostopic",
12 "rosnode",
13 "rosbag",
14 "ros2",
15 "ros1_bridge",
16 "rmw", # ROS middleware
17 "fastrtps",
18 "cyclonedds",
19 "rclcpp",
20 "rclpy",
21 "noetic",
22 "foxy",
23 "humble",
24}

Definition at line 10 of file monitor-ros-cpu.py.