1717 from MAVProxy .modules .lib .mp_menu import MPMenuCallTextDialog
1818 from MAVProxy .modules .lib .mp_menu import MPMenuItem
1919
20+ DEFAULT_CIRCLE_SIZE = 500
21+
2022
2123class FenceModule (mission_item_protocol .MissionItemProtocolModule ):
2224 '''uses common MISSION_ITEM protocol base class to provide fence
@@ -28,6 +30,7 @@ def __init__(self, mpstate):
2830 self .present = False
2931 self .enabled = False
3032 self .healthy = True
33+ self .last_home_change = 0
3134
3235 def gui_menu_items (self ):
3336 ret = super (FenceModule , self ).gui_menu_items ()
@@ -36,14 +39,14 @@ def gui_menu_items(self):
3639 'Add Inclusion Circle' , 'Add Inclusion Circle' , '# fence addcircle inc ' ,
3740 handler = MPMenuCallTextDialog (
3841 title = 'Radius (m)' ,
39- default = 500
42+ default = DEFAULT_CIRCLE_SIZE
4043 )
4144 ),
4245 MPMenuItem (
4346 'Add Exclusion Circle' , 'Add Exclusion Circle' , '# fence addcircle exc ' ,
4447 handler = MPMenuCallTextDialog (
4548 title = 'Radius (m)' ,
46- default = 500
49+ default = DEFAULT_CIRCLE_SIZE
4750 )
4851 ),
4952 MPMenuItem (
@@ -55,6 +58,13 @@ def gui_menu_items(self):
5558 MPMenuItem (
5659 'Add Return Point' , 'Add Return Point' , '# fence addreturnpoint' ,
5760 ),
61+ MPMenuItem (
62+ 'Add Home Centered Inclusion Circle' , 'Add Home Inclusion Circle' , '# fence addhomecircle ' ,
63+ handler = MPMenuCallTextDialog (
64+ title = 'Radius (m)' ,
65+ default = DEFAULT_CIRCLE_SIZE
66+ )
67+ ),
5868 ])
5969 return ret
6070
@@ -69,6 +79,12 @@ def count(self):
6979 '''return number of waypoints'''
7080 return self .wploader .count ()
7181
82+ def last_change (self ):
83+ base_class_last_change = super ().last_change ()
84+ if self .last_home_change > base_class_last_change :
85+ return self .last_home_change
86+ return base_class_last_change
87+
7288 def circles_of_type (self , t ):
7389 '''return a list of Circle fences of a specific type - a single
7490 MISSION_ITEM'''
@@ -81,12 +97,28 @@ def circles_of_type(self, t):
8197 return []
8298 if p .command != t :
8399 continue
100+ if t == mavutil .mavlink .MAV_CMD_NAV_FENCE_HOME_CIRCLE_INCLUSION :
101+ def no_home_error ():
102+ print ("Error - no home yet. Try again later." )
103+
104+ if self .module ('wp' ) is not None :
105+ home = self .module ('wp' ).get_home ()
106+ if home is None :
107+ no_home_error ()
108+ return
109+ else :
110+ no_home_error ()
111+ return
112+ p .x = home .x # x (latitude)
113+ p .y = home .y # y (longitude)
114+
84115 ret .append (p )
85116 return ret
86117
87118 def inclusion_circles (self ):
88119 '''return a list of Circle inclusion fences - a single MISSION_ITEM each'''
89- return self .circles_of_type (mavutil .mavlink .MAV_CMD_NAV_FENCE_CIRCLE_INCLUSION )
120+ return self .circles_of_type (mavutil .mavlink .MAV_CMD_NAV_FENCE_CIRCLE_INCLUSION ) + \
121+ self .circles_of_type (mavutil .mavlink .MAV_CMD_NAV_FENCE_HOME_CIRCLE_INCLUSION )
90122
91123 def exclusion_circles (self ):
92124 '''return a list of Circle exclusion fences - a single MISSION_ITEM each'''
@@ -222,9 +254,15 @@ def handle_sys_status(self, m):
222254 elif self .enabled is True and self .healthy is False :
223255 self .console .set_status ('Fence' , 'FEN' , row = 0 , fg = 'red' )
224256
257+ def handle_home_position (self , m ):
258+ self .last_home_change = time .time () # see self.last_change in mavwp.py
259+
225260 def mavlink_packet (self , m ):
226- if m .get_type () == 'SYS_STATUS' and self .message_is_from_primary_vehicle (m ):
261+ m_type = m .get_type ()
262+ if m_type == 'SYS_STATUS' and self .message_is_from_primary_vehicle (m ):
227263 self .handle_sys_status (m )
264+ elif m_type == 'HOME_POSITION' :
265+ self .handle_home_position (m )
228266 super (FenceModule , self ).mavlink_packet (m )
229267
230268 def apply_function_to_points (self , function ):
@@ -341,6 +379,35 @@ def cmd_addcircle(self, args):
341379 self .append (m )
342380 self .send_all_items ()
343381
382+ def cmd_addhomecircle (self , args ):
383+ '''adds a home-centered circle to the map with given radius'''
384+ if not self .check_have_list ():
385+ return
386+ if len (args ) < 1 :
387+ print ("Usage: fence addhomecircle RADIUS" )
388+ return
389+ radius = float (args [0 ])
390+
391+ m = mavutil .mavlink .MAVLink_mission_item_int_message (
392+ self .target_system ,
393+ self .target_component ,
394+ 0 , # seq
395+ mavutil .mavlink .MAV_FRAME_GLOBAL , # frame
396+ mavutil .mavlink .MAV_CMD_NAV_FENCE_HOME_CIRCLE_INCLUSION , # command
397+ 0 , # current
398+ 0 , # autocontinue
399+ radius , # param1,
400+ 0.0 , # param2,
401+ 0.0 , # param3
402+ 0.0 , # param4
403+ 0 , # x (latitude), ignored
404+ 0 , # y (longitude), ignored
405+ 0 , # z (altitude)
406+ self .mav_mission_type (),
407+ )
408+ self .append (m )
409+ self .send_all_items ()
410+
344411 def cmd_addreturnpoint (self , args ):
345412 '''adds a returnpoint at the map click location'''
346413 if not self .check_have_list ():
@@ -569,6 +636,7 @@ def is_circle_item(self, item):
569636 return item .command in [
570637 mavutil .mavlink .MAV_CMD_NAV_FENCE_CIRCLE_EXCLUSION ,
571638 mavutil .mavlink .MAV_CMD_NAV_FENCE_CIRCLE_INCLUSION ,
639+ mavutil .mavlink .MAV_CMD_NAV_FENCE_HOME_CIRCLE_INCLUSION ,
572640 ]
573641
574642 def find_polygon_point (self , polygon_start_seq , item_offset ):
@@ -784,6 +852,7 @@ def commands(self):
784852 ret = super (FenceModule , self ).commands ()
785853 ret .update ({
786854 'addcircle' : (self .cmd_addcircle , ["<inclusion|inc|exclusion|exc>" , "RADIUS" ]),
855+ 'addhomecircle' : (self .cmd_addhomecircle , ["RADIUS" ]),
787856 'movecircle' : (self .cmd_movecircle , []),
788857 'setcircleradius' : (self .cmd_setcircleradius , ["seq radius" ]),
789858 'addpoly' : (self .cmd_addpoly , ["<inclusion|inc|exclusion|exc>" , "<radius>" "<pointcount>" , "<rotation>" ]),
0 commit comments