44import time
55from MAVProxy .modules .lib import mp_module
66from MAVProxy .modules .lib import mp_settings
7+ from pymavlink import mavutil
78
89class WarningModule (mp_module .MPModule ):
910 def __init__ (self , mpstate ):
@@ -12,19 +13,26 @@ def __init__(self, mpstate):
1213 self .check_time = time .time ()
1314 self .warn_time = time .time ()
1415 self .failure = None
15- self .details = ""
16+ self .details = []
1617 self .warning_settings = mp_settings .MPSettings (
1718 [ ('warn_time' , int , 5 ),
1819 ('details' , bool , True ),
1920 ('min_sat' , int , 10 ),
2021 ('sat_diff' , int , 5 ),
22+ ('alt_diff' , int , 20 ),
2123 ('airspd_diff' , float , 5 ),
24+ ('airspd_age' , float , 5 ),
2225 ('esc_group1' , int , 0 ),
2326 ('esc_group2' , int , 0 ),
2427 ('esc_min_rpm' , int , 100 ),
2528 ])
2629 self .add_completion_function ('(WARNINGSETTING)' ,
2730 self .warning_settings .completion )
31+ # variables for monitoring airspeed changes
32+ self .last_as1 = 0
33+ self .last_as2 = 0
34+ self .last_as1_change = time .time ()
35+ self .last_as2_change = time .time ()
2836
2937 def cmd_warning (self , args ):
3038 '''warning commands'''
@@ -33,7 +41,7 @@ def cmd_warning(self, args):
3341 if args [0 ] == 'set' :
3442 state .warning_settings .command (args [1 :])
3543 if args [0 ] == 'details' :
36- print ("warning: %s" % self .details )
44+ print ("warning: %s" % '|' . join ( self .details ) )
3745 else :
3846 print ('usage: warning set|details' )
3947
@@ -69,10 +77,10 @@ def check_escs(self):
6977 '''check for ESC consistency'''
7078 rpms = self .get_esc_rpms ()
7179 if self .check_esc_group (self .warning_settings .esc_group1 , rpms ):
72- self .details = "ESC group1 fail"
80+ self .details . append ( "ESC group1 fail" )
7381 return True
7482 if self .check_esc_group (self .warning_settings .esc_group2 , rpms ):
75- self .details = "ESC group2 fail"
83+ self .details . append ( "ESC group2 fail" )
7684 return True
7785 return False
7886
@@ -82,13 +90,16 @@ def check_gps(self):
8290 gps2 = self .master .messages .get ("GPS2_RAW" , None )
8391 if gps1 and gps2 :
8492 if abs (gps1 .satellites_visible - gps2 .satellites_visible ) > self .warning_settings .sat_diff :
85- self .details = "GPS sat diff"
93+ self .details .append ("GPS sat diff" )
94+ return True
95+ if abs (gps1 .alt * 0.001 - gps2 .alt * 0.001 ) > self .warning_settings .alt_diff :
96+ self .details .append ("GPS alt diff" )
8697 return True
8798 if gps1 and gps1 .satellites_visible < self .warning_settings .min_sat :
88- self .details = "GPS1 low sat count"
99+ self .details . append ( "GPS1 low sat count" )
89100 return True
90101 if gps2 and gps2 .satellites_visible < self .warning_settings .min_sat :
91- self .details = "GPS2 low sat count"
102+ self .details . append ( "GPS2 low sat count" )
92103 return True
93104 return False
94105
@@ -97,22 +108,64 @@ def check_airspeed(self):
97108 vfr_hud = self .master .messages .get ("VFR_HUD" , None )
98109 nvf_as2 = self .master .messages .get ("NAMED_VALUE_FLOAT[AS2]" , None )
99110 if vfr_hud and nvf_as2 :
100- if abs (vfr_hud .airspeed - nvf_as2 .value ) > self .warning_settings .airspd_diff :
101- self .details = "Airspeed difference"
111+ as1 = vfr_hud .airspeed
112+ as2 = nvf_as2 .value
113+ if abs (as1 - as2 ) > self .warning_settings .airspd_diff :
114+ self .details .append ("Airspeed difference" )
115+ return True
116+ now = time .time ()
117+ if as1 != self .last_as1 :
118+ self .last_as1 = as1
119+ self .last_as1_change = now
120+ if as2 != self .last_as2 :
121+ self .last_as2 = as2
122+ self .last_as2_change = now
123+ if as1 > 0 and now - self .last_as1_change > self .warning_settings .airspd_age :
124+ self .details .append ("Airspeed1 age" )
125+ return True
126+ if as2 > 0 and now - self .last_as2_change > self .warning_settings .airspd_age :
127+ self .details .append ("Airspeed2 age" )
102128 return True
103129 return False
104130
131+ def check_status (self ):
132+ '''check SYS_STATUS health bits'''
133+ status = self .master .messages .get ("SYS_STATUS" , None )
134+ if not status :
135+ return False
136+ sensors = { 'AS' : mavutil .mavlink .MAV_SYS_STATUS_SENSOR_DIFFERENTIAL_PRESSURE ,
137+ 'MAG' : mavutil .mavlink .MAV_SYS_STATUS_SENSOR_3D_MAG ,
138+ 'INS' : mavutil .mavlink .MAV_SYS_STATUS_SENSOR_3D_ACCEL | mavutil .mavlink .MAV_SYS_STATUS_SENSOR_3D_GYRO ,
139+ 'AHRS' : mavutil .mavlink .MAV_SYS_STATUS_AHRS ,
140+ 'TERR' : mavutil .mavlink .MAV_SYS_STATUS_TERRAIN ,
141+ 'LOG' : mavutil .mavlink .MAV_SYS_STATUS_LOGGING ,
142+ 'FEN' : mavutil .mavlink .MAV_SYS_STATUS_GEOFENCE ,
143+ }
144+ health = status .onboard_control_sensors_health
145+ for sname in sensors :
146+ bits = sensors [sname ]
147+ if health & bits != bits :
148+ self .details .append ("status %s" % sname )
149+ return True
150+ return False
151+
105152 def check_all (self ):
153+ failures = []
106154 if self .check_escs ():
107- self .failure = 'ESC'
108- elif self .check_gps ():
109- self .failure = 'GPS'
110- elif self .check_airspeed ():
111- self .failure = 'AIRSPEED'
155+ failures .append ('ESC' )
156+ if self .check_gps ():
157+ failures .append ('GPS' )
158+ if self .check_airspeed ():
159+ failures .append ('AIRSPEED' )
160+ if self .check_status ():
161+ failures .append ('STATUS' )
162+ if len (failures ) > 0 :
163+ self .failure = '|' .join (failures )
112164
113165 def monitor (self ):
114166 last_fail = self .failure
115167 self .failure = None
168+ self .details = []
116169 self .check_all ()
117170 if self .failure and self .failure != last_fail :
118171 self .warn (self .failure )
0 commit comments