@@ -21,18 +21,19 @@ def __init__(self, srv: ServerBase, config=dict()) -> None:
2121
2222 self .requested_pages = ['Parameters' ]
2323
24- self .rate = config .get ('rate' , 10.0 )
25-
2624 self .srv = srv
2725
28- self .srv .schedule_task (self .run ())
29-
3026 self .srv .add_route ('GET' , '/parameters/info' ,
3127 self .parameters_get_info ,
3228 'parameters_get_info' )
3329
30+ self .srv .add_route ('POST' , '/parameters/set_value' ,
31+ self .parameters_set_value ,
32+ 'parameters_set_value' )
33+
3434 # subscribe to stats
3535 self .get_info = rospy .ServiceProxy ('xbotcore/get_parameter_info' , GetParameterInfo )
36+ self .set_parameters = rospy .ServiceProxy ('xbotcore/set_parameters' , SetString )
3637
3738
3839 @utils .handle_exceptions
@@ -50,204 +51,19 @@ async def parameters_get_info(self, request):
5051 'descriptor' : [json .dumps (yaml .safe_load (v )) for v in response .descriptor ]
5152 }
5253 )
54+
55+ @utils .handle_exceptions
56+ async def parameters_set_value (self , request : web .Request ):
5357
58+ body = await request .text ()
5459
55- @utils .handle_exceptions
56- async def dashboard_robot_switch (self , request : web .Request ):
57-
58- # we need the command name (start or stop)
59- command = request .match_info .get ('command' , None )
60-
61- l : launcher .Launcher = self .get_launcher ()
62-
63- if command == 'start' :
64-
65- # start ecat
66- await self .send_status ('starting robot 1/3 (ecat)' )
67-
68- if not await l .start (process = 'ecat' ):
69- raise RuntimeError ('could not start ecat' )
70-
71- # check slaves
72- await self .send_status ('starting robot 2/3 (ecat_slave_check)' )
73-
74- if not await l .start (process = 'wait_ecat_online' ):
75- raise RuntimeError ('could not find slaves' )
76-
77- await self .send_status ('starting robot 3/3 (xbot2)' )
78-
79- # start xbot2
80- if not await l .start (process = 'xbot2' ,
81- user_variants = ['ec_imp' ]):
82- raise RuntimeError ('could not start xbot2' )
83-
84- # wait alive
85- while not self .xbot2_alive :
86- await asyncio .sleep (0.1 )
87-
88- self .active_state = 'ready'
89-
90- elif command == 'stop' :
91-
92- # check xbot2 is down
93- sdict = await l .status ()
94-
95- if sdict .get ('xbot2' , '' ) == 'Running' :
96- raise RuntimeError ('xbot2 is up: have you pressed the emergency button?' )
97-
98- # kill ecat and hope for the best
99- await self .send_status ('stopping robot (ecat)' )
100-
101- if not await l .kill (process = 'ecat' , graceful = True ):
102- raise RuntimeError ('could not stop ecat' )
103-
104- self .active_state = 'inactive'
105-
106- else :
107-
108- raise KeyError (f'bad command { command } ' )
109-
110-
111- return web .Response (text = json .dumps (
112- {
113- 'success' : True ,
114- 'message' : 'ok' ,
115- }
116- ))
60+ print (body )
11761
62+ res = await utils .to_thread (self .set_parameters , request = body )
11863
119- @utils .handle_exceptions
120- async def dashboard_start (self , request : web .Request ):
121-
122- # check xbot2 alive
123- if self .stats is None :
124- raise RuntimeError ('xbot2 is not alive' )
125-
126- # we need the task name and ctrl mode
127- task_name = request .match_info .get ('task_name' , None )
128-
129- if task_name is None :
130- raise ValueError ('no task name specified in url' )
131-
132- task = self .states [task_name ]
133-
134- # stop all plugins
135- all_plugins = [t .name for t in self .stats .task_stats if t .name in self .all_plugins ]
136- plugins_to_start = plugins = task ['plugin' ]
137- plugins_to_stop = [p for p in all_plugins if p not in plugins_to_start ]
138-
139- for p in plugins_to_stop :
140- await self .send_status (f'stopping plugin { p } ' )
141- await self .plugin_switch (p , 0 )
142-
143- for p in plugins_to_stop :
144- await self .send_status (f'waiting for plugin { p } to stop...' )
145- await asyncio .wait_for (self .wait_for_state (p , ['Stopped' , 'Initialized' ]),
146- timeout = 10.0 )
147-
148- # start required plugins
149- for p in plugins_to_start :
150- await self .send_status (f'starting plugin { p } ' )
151- await self .plugin_switch (p , 1 )
152- for p in plugins_to_start :
153- await self .send_status (f'waiting for plugin { p } to start...' )
154- await self .wait_for_state (p , 'Running' )
155-
156- # kill all active processes
157- process_to_start = task ['process' ]
158- process_to_stop = [p for p in self .all_processes if p not in process_to_start ]
159- for p in process_to_stop :
160- await self .send_status (f'killing process { p } ' )
161- l : launcher .Launcher = self .get_launcher ()
162- await asyncio .wait_for (l .kill (process = p , graceful = True ),
163- timeout = 30 )
164-
165- # start required processes
166- for p in process_to_start :
167- await self .send_status (f'starting process { p } ' )
168- l : launcher .Launcher = self .get_launcher ()
169- await asyncio .wait_for (l .start (process = p ),
170- timeout = 30 )
171-
172-
173- await self .send_status (f'done' )
174-
175- self .active_state = task_name
176-
177- return web .Response (text = json .dumps (
64+ return web .json_response (
17865 {
179- 'success' : True ,
180- 'message' : 'ok' ,
66+ 'success' : res . success ,
67+ 'message' : res . message
18168 }
182- ))
183-
184-
185- async def plugin_switch (self , plugin_name , switch_flag ):
186- switch = rospy .ServiceProxy (f'xbotcore/{ plugin_name } /switch' , service_class = SetBool )
187- await utils .to_thread (switch .wait_for_service , timeout = 1.0 )
188- res = await utils .to_thread (switch , switch_flag )
189- return res .success
190-
191-
192- async def run (self ):
193-
194- while True :
195-
196- # if not self.xbot2_alive:
197- # self.active_state = 'inactive'
198- # elif self.active_state == 'inactive':
199- # self.active_state = 'ready'
200-
201- # self.xbot2_alive = False
202-
203- await self .srv .ws_send_to_all (
204- {
205- 'type' : 'dashboard_msg' ,
206- 'active_state' : self .active_state
207- }
208- )
209-
210- await asyncio .sleep (0.666 )
211-
212-
213- def on_stats_recv (self , msg ):
214- self .stats = msg
215- self .xbot2_alive = True
216-
217-
218-
219- async def wait_for_state (self , plugin_name , state ):
220-
221- if isinstance (state , str ):
222- state = [state ]
223-
224- idx = - 1
225-
226- for i , t in enumerate (self .stats .task_stats ):
227- if t .name in plugin_name :
228- idx = i
229- break
230-
231- if idx == - 1 :
232- raise KeyError (plugin_name )
233-
234- while self .stats .task_stats [idx ].state not in state :
235- await asyncio .sleep (0.1 )
236-
237-
238- def get_launcher (self ):
239- if self .launcher is not None :
240- return self .launcher
241- for e in self .srv .extensions :
242- if isinstance (e , launcher .Launcher ):
243- self .launcher = e
244- return e
245- raise ValueError ('launcher unavailable' )
246-
247-
248- async def send_status (self , txt ):
249- print (txt )
250- await self .srv .ws_send_to_all (
251- dict (type = 'dashboard_msg' ,
252- msg = txt )
25369 )
0 commit comments