-
Notifications
You must be signed in to change notification settings - Fork 142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature Request: LaunchService wrapper for easy non-blocking launch and shutdown #724
Comments
HI @KKSTB, I am trying to replicate what you described in this issue, but for me this code is still blocking. Can you help me out? This is what I have so far:
However, when I call Thanks in advance! |
Hi @Rezenders. I used it in a large project to launch many other python launch files without problem. Maybe you can try the followings to see what's wrong:
|
I did encounter some problem when my project grows to use several event loops. So a slight change to the code in OP is needed: From: loop = asyncio.get_event_loop() To: loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop) |
I would have expected something like this to work, but it doesn't: from launch import LaunchService, LaunchDescription
from launch.actions import IncludeLaunchDescription
from ament_index_python.packages import get_package_share_directory
from launch.launch_description_sources import AnyLaunchDescriptionSource
import pathlib
from multiprocessing import Process
import time
def get_launch_file(package_name, launch_file_name):
path = pathlib.Path(get_package_share_directory(package_name), "launch", launch_file_name)
assert path.exists()
return path
def app_srv_via_launch_xml(app):
"""Provides a launch services for an application in the foreground.
Assumes it has an XML launch file.
Args:
app (str): The application name, ie "demo_pkg".
"""
launch_file = get_launch_file(app, f"{app}.launch.xml")
ld = LaunchDescription(
[
IncludeLaunchDescription(AnyLaunchDescriptionSource([str(launch_file)])),
]
)
service = LaunchService()
service.include_launch_description(ld)
return service
def main():
app_name = "demo_pkg"
service = app_srv_via_launch_xml(app_name)
demo_pkg_process = Process(target=service.run, daemon=True)
demo_pkg_process.start()
time.sleep(10)
demo_pkg_process.terminate()
print("Done")
if __name__=="__main__":
main() The process exits cleanly, but the |
This is because using SIGTERM can result in orphaned processes (https://github.com/ros2/launch/blob/d9ffd805e3d9ca42fe4dd0019ae095e9eb0d4d72/launch/launch/launch_service.py#L209C53-L209C85). To shutdown children processes, LaunchService.shutdown() should be called. Another method is to send SIGINT. And since there is no way to send SIGINT to the LaunchService in your example, this run method probably cannot shutdown children processes once started. |
Feature request
Feature description
LaunchService
has puzzled many people as to how to properly launch aLaunchDescription
without blocking the main thread:#210
https://answers.ros.org/question/321118/ros2-nodes-occasionally-dying-using-launchservice-in-a-subprocess/
#126
So I propose either adding a
start()
function toLaunchService
, or a new wrapper class, that spawns a daemon process to run the async launch loop, like this:Implementation considerations
Besides launching a
LaunchDescription
, it would be better if there is another mode of launching an individual node and get its PID to operate the process, just like ROS1 does.The text was updated successfully, but these errors were encountered: