class Orocos::ROS::LauncherProcess

Management of a roslaunch process and its underlying launch file

Attributes

launcher[R]
pid[R]

The process ID of this process on the machine of the process server

ros_process_server[R]

Public Class Methods

new(ros_process_server, name, model) click to toggle source
Calls superclass method Orocos::ProcessBase.new
# File lib/orocos/ros/process_manager.rb, line 140
def initialize(ros_process_server, name, model)
    @ros_process_server = ros_process_server
    @nodes = Hash.new
    @launcher = model
    @pid = nil
    super(name, model)
end
parse_run_options(*names) click to toggle source

Parse run options to @return [String, Hash] Names and options

# File lib/orocos/ros/process_manager.rb, line 123
def self.parse_run_options(*names)
    options = names.last.kind_of?(Hash) ? names.pop : Hash.new
    [ names, options ]
end

Public Instance Methods

alive() click to toggle source
# File lib/orocos/ros/process_manager.rb, line 138
def alive; !!@pid end
alive?() click to toggle source

True if the process is running. This is an alias for running?

# File lib/orocos/ros/process_manager.rb, line 180
def alive?; !!@pid end
dead!(exit_status) click to toggle source

Called to announce that this process has quit

# File lib/orocos/ros/process_manager.rb, line 276
def dead!(exit_status)
    LauncherProcess.debug "Announcing launcher '#{@launcher.name}', pid #{@pid} dead!"
    @pid = nil
end
host_id() click to toggle source
# File lib/orocos/ros/process_manager.rb, line 136
def host_id; 'localhost' end
kill(wait = true) click to toggle source

Kill the launcher

# File lib/orocos/ros/process_manager.rb, line 266
def kill(wait = true)
    LauncherProcess.debug "Sending SIGTERM to launcher '#{@launcher.name}', pid #{@pid}. Nodes #{@launcher.nodes.map(&:name).join(", ")} will be teared down."
    ::Process.kill('SIGTERM', @pid)
    ros_process_server.kill(self)
    if wait
        status = @launcher.wait_termination
    end
end
on_localhost?() click to toggle source
# File lib/orocos/ros/process_manager.rb, line 137
def on_localhost?; true end
running?() click to toggle source

True if the process is running. This is an alias for alive?

# File lib/orocos/ros/process_manager.rb, line 182
def running?; alive? end
spawn(options = Hash.new) click to toggle source

Spawn the launch file @return [int] pid of the launch process

# File lib/orocos/ros/process_manager.rb, line 150
def spawn(options = Hash.new)
    options, unknown_options = Kernel.filter_options options,
        :wait => false,
        :redirect => "ros-#{@launcher.name}.txt"

    wait = options[:wait]
    options.delete(:wait)
    options.merge!(unknown_options)

    task_names.each do |name|
        if ros_process_server.name_service.task_reachable?(name)
            raise ArgumentError, "there is already a task called '#{name}', are you starting the same component twice ?"
        end
    end

    LauncherProcess.debug "Launcher '#{@launcher.name}' spawning"
    @pid = Orocos::ROS.roslaunch(@launcher.project.name, @launcher.name, options)
    LauncherProcess.info "Launcher '#{@launcher.name}' started, pid '#{@pid}'. Nodes #{@launcher.nodes.map(&:name).join(", ")}  available."

    @pid
end
task(name) click to toggle source

Retrieve the task (node) using the internal name service instance @return [Orocos::ROS::Node] A task (node) instance @raise [Orocos::NotFound] If task (node) cannot be found in the name service

Calls superclass method Orocos::ProcessBase#task
# File lib/orocos/ros/process_manager.rb, line 175
def task(name)
    super(name, ros_process_server.name_service)
end
wait_running(timeout = nil) click to toggle source

Wait for all nodes of the launcher to become available @raise [Orocos::NotFound] if the nodes are not available after a given timeout @return [Boolean] True if process is running, false otherwise

# File lib/orocos/ros/process_manager.rb, line 187
def wait_running(timeout = nil)

    is_running = Orocos::Process.wait_running(self,timeout) do |launcher_process|
        all_nodes_available = true
        all_topics_available = true
        topics = []
        begin
            nodes = launcher_process.launcher.nodes
            if nodes.empty?
                LauncherProcess.warn "launcher_process: #{launcher_process} does not have any nodes"
            end

            nodes.each do |n|
                # Wait till node is visible in ROS
                if !ROS.rosnode_running?(n.name)
                    all_nodes_available = false
                    break
                end

                # Check if the node can be seen in the nameservice as
                # well
                task = ros_process_server.name_service.get(n.name)

                # Try to check whether the topics in the spec are already available
                # Note that we have to try to instanciate write and reader and using
                # to_orocos_port in order to make sure the ROS node is really accessible
                if spec = ROS.node_spec_by_node_name(n.name)
                    spec.each_input_port do |port|
                        if task.port(port.topic_name)
                            topics << port.topic_name
                            next
                        end

                        all_topics_available = false
                        break
                    end

                    spec.each_output_port do |port|
                        if task.port(port.topic_name)
                            topics << port.topic_name
                            next
                        end
                        all_topics_available = false
                        break
                    end
                else
                    raise ArgumentError, "No ROS Node specification available for #{n.name}"
                end
            end
        rescue Orocos::NotFound => e
            all_nodes_available = false
            all_topics_available = false
        end

        if ! (all_nodes_available && all_topics_available)
            LauncherProcess.debug "reachable nodes: #{nodes.map(&:name).join(", ")}"
            LauncherProcess.debug "reachable topics: #{topics.join(", ")}"
        end

        all_nodes_available && all_topics_available
    end

    is_running
end
wait_termination(timeout = nil) click to toggle source

Wait for termination of the launcher process @return [Process::Status] Final process status

# File lib/orocos/ros/process_manager.rb, line 254
def wait_termination(timeout = nil)
    if timeout
        raise NotImplementedError, "ROS::ProcessManager#wait_termination cannot be called with a timeout"
    end

    _, status = begin ::Process.waitpid2(@pid, ::Process::WUNTRACED | Process::WNOHANG)
                  rescue Errno::ECHILD
                  end
    status
end