class Orocos::ROS::LauncherProcess
Management of a roslaunch process and its underlying launch file
Attributes
The process ID of this process on the machine of the process server
Public Class Methods
# 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 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
# File lib/orocos/ros/process_manager.rb, line 138 def alive; !!@pid end
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
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
# File lib/orocos/ros/process_manager.rb, line 136 def host_id; 'localhost' end
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
# File lib/orocos/ros/process_manager.rb, line 137 def on_localhost?; true end
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 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
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
# File lib/orocos/ros/process_manager.rb, line 175 def task(name) super(name, ros_process_server.name_service) end
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 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