Is there a simple way to extract statistics on which tasks in the scheduler run overtime, by how much and how often they do? Something like the console command “nsh>perf” described here by @peterbarker ? I’m using a pixracer with ChibiOS so no nsh console if I understand correctly.
Instead I’ve built a small python script to automate some of the process. It works with SCHED_DEBUG=3 but it’s got the following drawbacks:
- doesn’t measure which percentage of each task runs overtime. It captures only the ones that run overtime
- necessitates too many steps: 1)run mavproxy connected to drone USB 2)pipe the output to a file and 3)process it with the python script
Question #2: does anybody know why some functionalities that should be disabled seem to be run by the scheduler and take up time (beacon, visual odometry, precision landing…) see comments in the right hand column below:
task name | average overrun | # of occurences | allowed time |
---|---|---|---|
10-update | 328 | 462 | 50 //AP_Proximity |
11-update | 252 | 920 | 50 //AP_Beacon: but BCN_TYPE is not enabled |
12-update | 268 | 987 | 50 //AP_VisualOdom: but VISO_TYPE is not enabled |
21-update_precland | 289 | 1225 | 50 //but PLND_ENABLED is not enabled |
22-fourhundred_hz_logging | 331 | 1322 | 50 //lots of those (fast IMU logging enabled) |
29-update_receive | 424 | 1604 | 180 //lots of those: receives packets from GCS with GCS_MAVLINK::update_receive() |
3-update | 304 | 236 | 160 //OpticalFlow: but FLOW_ENABLE=0 |
31-update_send | 1127 | 747 | 550 //long overruns: GCS_MAVLINK::update_send() |
23-update | 344 | 167 | 90 |
36-periodic_tasks | 478 | 875 | 300 //lots of those: AP_Logger_Backend::periodic_tasks() |
37-periodic | 502 | 1487 | 50 //lots of those: AP_InertialSensor: logs on SD card |
40-compass_cal_update | 306 | 651 | 100 //compass calibration runs continuously? |
9-read_rangefinder | 181 | 407 | 100 //lots of those: change maxTime? |
15-update_throttle_hover | 276 | 96 | 90 |
33-update_trigger | 294 | 97 | 75 |
35-twentyfive_hz_logging | 331 | 56 | 110 |
2-update_GPS | 535 | 217 | 200 //13% overrun over 30s test: change maxTime? |
19-update_events | 270 | 68 | 75 |
20-accumulate | 305 | 76 | 90 |
25-ekf_check | 315 | 55 | 75 |
28-lost_vehicle_check | 282 | 20 | 50 |
32-update | 337 | 104 | 75 |
44-terrain_update | 240 | 124 | 100 |
14-run_nav_updates | 261 | 47 | 100 |
45-update | 333 | 75 | 75 |
43-avoidance_adsb_update | 291 | 54 | 100 |
4-update_batt_compass | 309 | 52 | 120 |
5-read_aux_all | 327 | 59 | 50 |
6-arm_motors_check | 303 | 63 | 50 |
24-one_hz_loop | 204 | 20 | 100 |
47-update | 383 | 4 | 100 |
0-rc_loop | 151 | 24 | 130 |
39-rpm_update | 319 | 43 | 200 |
7-auto_disarm_check | 100 | 5 | 50 |
8-auto_trim | 211 | 8 | 75 |
1-throttle_loop | 138 | 37 | 75 |
34-ten_hz_logging_loop | 413 | 6 | 350 |
26-gpsglitch_check | 313 | 40 | 50 |
46-update | 335 | 27 | 100 |
41-accel_cal_update | 328 | 36 | 100 |
42-update | 336 | 44 | 100 |
16-save_position | 276 | 12 | 100 |
17-update | 313 | 12 | 90 |
27-landinggear_update | 336 | 12 | 75 |
38-update_logging | 431 | 3 | 75 |
18-three_hz_loop | 229 | 10 | 75 |
13-update_altitude | 200 | 17 | 100 |
30-gcs_send_heartbeat | 276 | 3 | 110 |
In case it’s useful to somebody else, here is the python script:
import re
#object to summarize each task result
class Task:
def __init__(self,name,time,maxTime):
self.name =name
self.totalT=time
self.occurences=1
self.maxTime=maxTime
self.averageTime=0
datafile = open("/home/clem/scheduler_output.txt",'r')
lines = datafile.readlines()
task_list = []
for line in lines:
#some lines are garbled, just remove them
scheduler_duplicate =re.findall("Scheduler",line)
overrun_duplicate = re.findall("overrun",line)
if len(scheduler_duplicate)==2 or len(overrun_duplicate)==2:
print "garbled line found: ", line.strip()
continue
#regex each element
name = re.findall("Scheduler overrun task\[(.*?)\]", line)
if name:
time = re.findall('\] \((.*?)\/',line)
allowed_time = re.findall("\/(.*?)\)",line)
#print name, " ", time, " ", allowed_time
#check if the task has already been seen
task_exists = False
for task in task_list:
#update task if found
if task.name == name[0]:
task_exists = True
task.totalT += int(time[0])
task.occurences +=1
if not task_exists:
#add task to the list
task_list.append(Task(name[0],int(time[0]),allowed_time[0]))
#display final results
print "\nSummary results:"
print "{0:30}\t{1:^20}\t{2:^10}\t{3:^20}".format("task name","average overrun","# of occurences","allowed time")
for task in task_list:
task.averageTime = task.totalT/task.occurences
print "{0:30}\t{1:^20}\t{2:^10}\t{3:^20}".format(task.name,task.averageTime,task.occurences,task.maxTime)