Class: Orocos::ROS::LauncherProcess
- Inherits:
-
ProcessBase
- Object
- ProcessBase
- Orocos::ROS::LauncherProcess
- Defined in:
- lib/orocos/ros/process_manager.rb
Overview
Management of a roslaunch process and its underlying launch file
Instance Attribute Summary collapse
-
#launcher ⇒ Object
readonly
Returns the value of attribute launcher.
-
#pid ⇒ Object
readonly
The process ID of this process on the machine of the process server.
-
#ros_process_server ⇒ Object
readonly
Returns the value of attribute ros_process_server.
Attributes inherited from ProcessBase
#default_logger, #logged_ports, #model, #name, #name_mappings, #tasks
Class Method Summary collapse
-
.parse_run_options(*names) ⇒ String, Hash
Parse run options to.
Instance Method Summary collapse
- #alive ⇒ Object
-
#alive? ⇒ Boolean
True if the process is running.
-
#dead!(exit_status) ⇒ Object
Called to announce that this process has quit.
- #host_id ⇒ Object
-
#initialize(ros_process_server, name, model) ⇒ LauncherProcess
constructor
A new instance of LauncherProcess.
-
#kill(wait = true) ⇒ Object
Kill the launcher.
- #on_localhost? ⇒ Boolean
-
#running? ⇒ Boolean
True if the process is running.
-
#spawn(options = Hash.new) ⇒ int
Spawn the launch file.
-
#task(name) ⇒ Orocos::ROS::Node
Retrieve the task (node) using the internal name service instance.
-
#wait_running(timeout = nil) ⇒ Boolean
Wait for all nodes of the launcher to become available.
-
#wait_termination(timeout = nil) ⇒ Process::Status
Wait for termination of the launcher process.
Methods inherited from ProcessBase
#default_log_file_name, #default_logger_name, #each_task, #get_mapped_name, #log_all_ports, #map_name, #orogen, #register_task, resolve_prefix, #setup_default_logger, #task_names
Constructor Details
#initialize(ros_process_server, name, model) ⇒ LauncherProcess
Returns a new instance of LauncherProcess
140 141 142 143 144 145 146 |
# 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 |
Instance Attribute Details
#launcher ⇒ Object (readonly)
Returns the value of attribute launcher
131 132 133 |
# File 'lib/orocos/ros/process_manager.rb', line 131 def launcher @launcher end |
#pid ⇒ Object (readonly)
The process ID of this process on the machine of the process server
134 135 136 |
# File 'lib/orocos/ros/process_manager.rb', line 134 def pid @pid end |
#ros_process_server ⇒ Object (readonly)
Returns the value of attribute ros_process_server
128 129 130 |
# File 'lib/orocos/ros/process_manager.rb', line 128 def ros_process_server @ros_process_server end |
Class Method Details
.parse_run_options(*names) ⇒ String, Hash
Parse run options to
123 124 125 126 |
# File 'lib/orocos/ros/process_manager.rb', line 123 def self.(*names) = names.last.kind_of?(Hash) ? names.pop : Hash.new [ names, ] end |
Instance Method Details
#alive ⇒ Object
138 |
# File 'lib/orocos/ros/process_manager.rb', line 138 def alive; !!@pid end |
#alive? ⇒ Boolean
True if the process is running. This is an alias for running?
180 |
# File 'lib/orocos/ros/process_manager.rb', line 180 def alive?; !!@pid end |
#dead!(exit_status) ⇒ Object
Called to announce that this process has quit
276 277 278 279 |
# 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 ⇒ Object
136 |
# File 'lib/orocos/ros/process_manager.rb', line 136 def host_id; 'localhost' end |
#kill(wait = true) ⇒ Object
Kill the launcher
266 267 268 269 270 271 272 273 |
# 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? ⇒ Boolean
137 |
# File 'lib/orocos/ros/process_manager.rb', line 137 def on_localhost?; true end |
#running? ⇒ Boolean
True if the process is running. This is an alias for alive?
182 |
# File 'lib/orocos/ros/process_manager.rb', line 182 def running?; alive? end |
#spawn(options = Hash.new) ⇒ int
Spawn the launch file
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/orocos/ros/process_manager.rb', line 150 def spawn( = Hash.new) , = Kernel. , :wait => false, :redirect => "ros-#{@launcher.name}.txt" wait = [:wait] .delete(:wait) .merge!() 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, ) LauncherProcess.info "Launcher '#{@launcher.name}' started, pid '#{@pid}'. Nodes #{@launcher.nodes.map(&:name).join(", ")} available." @pid end |
#task(name) ⇒ Orocos::ROS::Node
Retrieve the task (node) using the internal name service instance
175 176 177 |
# File 'lib/orocos/ros/process_manager.rb', line 175 def task(name) super(name, ros_process_server.name_service) end |
#wait_running(timeout = nil) ⇒ Boolean
Wait for all nodes of the launcher to become available
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# 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) ⇒ Process::Status
Wait for termination of the launcher process
254 255 256 257 258 259 260 261 262 263 |
# 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 |