Skip to content

Commit

Permalink
Merge pull request #127 from JdeRobot/issue-126
Browse files Browse the repository at this point in the history
Specific terminate functions for more granular control and GUI server proper shutdown
  • Loading branch information
pawanw17 authored Feb 19, 2024
2 parents a505ace + 5d808df commit c6db1c6
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 39 deletions.
2 changes: 1 addition & 1 deletion manager/libs/applications/compatibility/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def run(self) -> None:

def stop(self) -> None:
self._stop.set()
self.server.shutdown()
self.server.shutdown_gracefully()

def send(self, data):
if self.current_client is not None:
Expand Down
87 changes: 49 additions & 38 deletions manager/manager/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,29 +44,36 @@ class Manager:
# Transitions for state idle
{'trigger': 'connect', 'source': 'idle',
'dest': 'connected', 'before': 'on_connect'},

# Transitions for state connected
{'trigger': 'launch_world', 'source': 'connected',
'dest': 'world_ready', 'before': 'on_launch_world'},

# Transitions for state world ready
{'trigger': 'prepare_visualization',
'source': 'world_ready', 'dest': 'visualization_ready', 'before': 'on_prepare_visualization'},

# Transitions for state visualization_ready
{'trigger': 'run_application', 'source': [
'visualization_ready', 'paused'], 'dest': 'application_running', 'before': 'on_run_application'},

# Transitions for state application_running
{'trigger': 'pause', 'source': 'application_running',
'dest': 'paused', 'before': 'on_pause'},
# Transitions for state paused
{'trigger': 'resume', 'source': 'paused',
'dest': 'application_running', 'before': 'on_resume'},
{'trigger': 'terminate', 'source': ['visualization_ready','application_running', 'paused'],
'dest': 'visualization_ready', 'before': 'on_terminate'},
{'trigger': 'stop', 'source': [
'application_running', 'paused'], 'dest': 'visualization_ready', 'before': 'on_stop'},

# Transitions for terminate levels
{'trigger': 'terminate_application', 'source': ['visualization_ready','application_running', 'paused'],
'dest': 'visualization_ready', 'before': 'on_terminate_application'},
{'trigger': 'terminate_visualization', 'source': 'visualization_ready',
'dest': 'world_ready', 'before': 'on_terminate_visualization'},
{'trigger': 'terminate_universe', 'source': 'world_ready',
'dest': 'connected', 'before': 'on_terminate_universe'},

# Global transitions
{'trigger': 'disconnect', 'source': '*',
'dest': 'idle', 'before': 'on_disconnect'},

]

def __init__(self, host: str, port: int):
Expand Down Expand Up @@ -217,17 +224,29 @@ def on_run_application(self, event):
print('errors')
raise Exception(errors)
LogManager.logger.info("Run application transition finished")
def on_terminate(self, event):
"""Terminates the application"""

def on_terminate_application(self, event):

if self.application_process:
try:
stop_process_and_children(self.application_process)
self.application_process = None
self.pause_sim()
self.reset_sim()
except Exception:
LogManager.logger.exception("No application running")
print(traceback.format_exc())

def on_terminate_visualization(self, event):

self.visualization_launcher.terminate()
self.gui_server.stop()
self.gui_server = None

def on_terminate_universe(self, event):

self.world_launcher.terminate()

def on_disconnect(self, event):
try:
self.consumer.stop()
Expand Down Expand Up @@ -276,12 +295,28 @@ def on_resume(self, msg):
proc = psutil.Process(self.application_process.pid)
proc.resume()
self.unpause_sim()
def pause_sim(self):
if "noetic" in str(self.ros_version):
rosservice.call_service("/gazebo/pause_physics", [])
else:
self.call_service("/pause_physics","std_srvs/srv/Empty")

def on_stop(self, event):
stop_process_and_children(self.application_process)
self.application_process = None
self.pause_sim()
self.reset_sim()
def unpause_sim(self):
if "noetic" in str(self.ros_version):
rosservice.call_service("/gazebo/unpause_physics", [])
else:
self.call_service("/unpause_physics","std_srvs/srv/Empty")

def reset_sim(self):
if "noetic" in str(self.ros_version):
rosservice.call_service("/gazebo/reset_world", [])
else:
self.call_service("/reset_world","std_srvs/srv/Empty")

def call_service(self, service, service_type):
command = f"ros2 service call {service} {service_type}"
subprocess.call(f"{command}", shell=True, stdout=sys.stdout, stderr=subprocess.STDOUT, bufsize=1024,
universal_newlines=True)

def start(self):
"""
Expand Down Expand Up @@ -346,30 +381,6 @@ def signal_handler(sign, frame):
self.consumer.send_message(ex)
LogManager.logger.error(e, exc_info=True)

def pause_sim(self):
if "noetic" in str(self.ros_version):
rosservice.call_service("/gazebo/pause_physics", [])
else:
self.call_service("/pause_physics","std_srvs/srv/Empty")

def unpause_sim(self):
if "noetic" in str(self.ros_version):
rosservice.call_service("/gazebo/unpause_physics", [])
else:
self.call_service("/unpause_physics","std_srvs/srv/Empty")

def reset_sim(self):
if "noetic" in str(self.ros_version):
rosservice.call_service("/gazebo/reset_world", [])
else:
self.call_service("/reset_world","std_srvs/srv/Empty")

def call_service(self, service, service_type):
command = f"ros2 service call {service} {service_type}"
subprocess.call(f"{command}", shell=True, stdout=sys.stdout, stderr=subprocess.STDOUT, bufsize=1024,
universal_newlines=True)


if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser()
Expand Down

0 comments on commit c6db1c6

Please sign in to comment.