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 106 of file monitor-ros-cpu.py.

107 """
108 Try to get ROS-related environment variables for a process
109 """
110 try:
111 proc = psutil.Process(pid)
112 env = proc.environ()
113 ros_env = {k: v for k, v in env.items() if "ROS" in k}
114 return bool(ros_env)
115 except (psutil.NoSuchProcess, psutil.AccessDenied):
116 return False
117
118
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 88 of file monitor-ros-cpu.py.

88def is_ros_related_process(proc_info, cmdline):
89 """
90 Check if a process is ROS-related based on name and command line
91 """
92 # Convert process information to lowercase for case-insensitive matching
93 name_lower = proc_info["name"].lower()
94 cmdline_lower = cmdline.lower()
95
96 # Check exclusions first
97 if any(excl in name_lower or excl in cmdline_lower for excl in EXCLUDE_KEYWORDS):
98 return False
99
100 # Check for ROS-related keywords in process name and command line
101 return any(
102 keyword in name_lower or keyword in cmdline_lower for keyword in ROS_KEYWORDS
103 )
104
105
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 119 of file monitor-ros-cpu.py.

119def main():
120 args = parse_args()
121
122 # Add any additional include patterns from command line
123 if args.include_pattern:
124 additional_patterns = set(args.include_pattern.split(","))
125 ROS_KEYWORDS.update(additional_patterns)
126
127 output_file = setup_logging_directory(args.output_dir)
128
129 with open(output_file, mode="a") as file:
130 writer = csv.writer(file)
131 writer.writerow(
132 [
133 "Timestamp",
134 "PID",
135 "Process Name",
136 "CPU (%)",
137 "Memory (%)",
138 "Command Line",
139 "Total CPU (%)",
140 "Total CPU Num",
141 "Total Memory (%)",
142 "Total Memory (GB)",
143 ]
144 )
145
146 print(f"Starting to monitor the CPU usage data and saving to: {output_file}")
147
148 # Total CPU and memory size in GB doesn't change
149 total_memory_gb = psutil.virtual_memory().total / (1024**3)
150 total_cpus = os.cpu_count()
151
152 while True:
153 timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
154 total_cpu_percent = psutil.cpu_percent(interval=None)
155 total_memory_percent = (
156 psutil.virtual_memory().percent
157 ) # Get total memory usage
158
159 for proc in psutil.process_iter(
160 ["pid", "name", "cpu_percent", "memory_percent", "cmdline"]
161 ):
162 try:
163 cmdline = (
164 " ".join(proc.info["cmdline"]) if proc.info["cmdline"] else ""
165 )
166
167 if is_ros_related_process(proc.info, cmdline):
168 pid = proc.info["pid"]
169 name = proc.info["name"]
170 cpu_percent = proc.info["cpu_percent"]
171 memory_percent = proc.info["memory_percent"]
172
173 writer.writerow(
174 [
175 timestamp,
176 pid,
177 name,
178 cpu_percent,
179 memory_percent,
180 cmdline,
181 total_cpu_percent,
182 total_cpus,
183 total_memory_percent,
184 total_memory_gb,
185 ]
186 )
187
188 except (
189 psutil.NoSuchProcess,
190 psutil.AccessDenied,
191 psutil.ZombieProcess,
192 ):
193 continue
194
195 time.sleep(1)
196
197
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 64 of file monitor-ros-cpu.py.

64def parse_args():
65 parser = argparse.ArgumentParser(description="Monitor CPU usage of ROS2 nodes")
66 parser.add_argument(
67 "--output-dir",
68 "-o",
69 default="carma-cpu-usage-logs",
70 help="Directory to store output files (default: carma-cpu-usage-logs)",
71 )
72 parser.add_argument(
73 "--include-pattern",
74 "-i",
75 help="Additional comma-separated patterns to include in process filtering",
76 )
77 return parser.parse_args()
78
79

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 80 of file monitor-ros-cpu.py.

80def setup_logging_directory(output_dir):
81 if not os.path.exists(output_dir):
82 os.makedirs(output_dir)
83 timestamp = datetime.now().strftime("%Y_%m_%d-%H_%M_%S")
84 filename = f"cpu_usage_ros2_nodes_{timestamp}.csv"
85 return os.path.join(output_dir, filename)
86
87

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 61 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 34 of file monitor-ros-cpu.py.