0
$\begingroup$

Rosanswers logo

Hello
I have a ros launch file that starts a few nodes. One of them exits under some conditions and I want to restart it every time when that happens. The whole idea is that I have a process that runs my simulator (specifically Webots). I have another process that starts a controller for my robot and whenever I reset the simulation I want to be able to restart my controller node without everything shutting down. What I have now is (it is a bit 'stupid' but I do not have any better ideas):

   controller =  Node(
        package=my_package,
        executable=my_executable,
    )

   cmd = ['ros2', 'run', 'my_package', 'my_executable']
   restart_controller = ExecuteProcess(cmd=cmd,shell=True)
 
   launch_description = LaunchDescription(ARGUMENTS + [
           robot_state_publisher,
           simulator,
           controller,

        # Restart controller when it breaks
        RegisterEventHandler(
            event_handler=launch.event_handlers.OnProcessExit(
                target_action=controller,
                on_exit=[restart_controller],
            )
        ),     

        RegisterEventHandler(
            event_handler=launch.event_handlers.OnProcessExit(
                target_action=restart_controller,
                on_exit=[controller],
            )
        ), 

        # Shutdown launch when Webots exits.
        RegisterEventHandler(
            event_handler=launch.event_handlers.OnProcessExit(
                target_action=simulator,
                on_exit=[EmitEvent(event=launch.events.Shutdown())],
            )
        )
    ])

If I start the controller node again and again from a terminal it works every time but here I see that in the ExecuteProcess method whenever I try to run the same process it crashes and raises a runtime error that says "ExecuteProcess action executed more than once".

Another thing is that the ros package is in Python (it cannot be in cpp for now at least) so it is not possible to make it a managed node and use the lifecycle utilities (configure-activate-shutdown etc.) which was my original idea.

I am also open to a better idea to do what I want if it is impossible to re-execute a process.


Originally posted by anastasiaPan on ROS Answers with karma: 123 on 2021-04-14

Post score: 1

$\endgroup$

2 Answers 2

0
$\begingroup$

Rosanswers logo

I have fixed this by switching to ROS rolling. Rolling distro has the option respawn in the ExecuteProcess.


Originally posted by anastasiaPan with karma: 123 on 2021-04-15

This answer was ACCEPTED on the original site

Post score: 3

$\endgroup$
0
$\begingroup$

Rosanswers logo

To handle the problem you can create function for controller description, and call it from on_exit() function, passed to the Event handler. Just don't use target_action argument, because it's comparing, using object. Than your on_exit_restart() function willl be called for each process, so just filter by name which process you want to restart:

    from launch_ros.actions import Node
    from launch.launch_context import LaunchContext
    from launch.events.process.process_exited import ProcessExited
    from launch.actions import RegisterEventHandler
    from launch import LaunchDescription
    from launch.event_handlers.on_process_exit import OnProcessExit

      
    def controller_description():
        return Node(
            package    = my_package,
            executable = my_executable
        )


    def on_exit_restart(event:ProcessExited, context:LaunchContext):
        print("\n\nProcess [{}] exited, pid: {}, return code: {}\n\n".format(
            event.action.name, event.pid, event.returncode))
        if event.returncode != 0 and 'controller' in event.action.name:
            return controller_description() # respawn node action


    ld = LaunchDescription([
        robot_state_publisher,
        simulator,
        controller,
        RegisterEventHandler(event_handler=OnProcessExit(on_exit=on_exit_restart))
    ])
          

Originally posted by yura_somatic with karma: 11 on 2021-06-18

This answer was NOT ACCEPTED on the original site

Post score: 1


Original comments

Comment by anastasiaPan on 2021-06-21:
Thank you for the answer! I am using the respawn feature for quite some time now and it works fine but I might try your solution too - just to verify!

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.