Integrating a Robot#
How to run open_apero_node on a robot of your own: the nodes to keep, what the robot provides and what to configure.
ROS Node, Launch Files and Messages describes the node.
Start from a copy of run_experiment_sim.launch: keep voxblox_node, open_apero_node and
mission_coordinator_node, and drop the HSSD scene-file loads, habitat_renderer_node, dummy_controller_node and,
unless an RGB-D camera publishes exactly synchronized camera info, RGB and 32-bit float depth,
rgbd_to_pointcloud_node. Give the coordinator <param name="wait_for_simulation" value="false"/>, or it waits for
Habitat and ends the launch after 30 s.
What the Robot Provides#
Commands: execute each
/command/trajectory(open_apero_msgs/RobotTrajectory, inmap_frame, a launch argument,worldby default). Its states hold the poses ofbase_frameandcamera_frame(x forward, z up) and atime_from_start,robot.time_step(0.2 s) apart; a planning command has at mostreplan_num_steps+ 1 (6 shipped) of them. The next command comes once this one is done.Pose with
use_tf: false(shipped, for a lockstep simulator): publish/robot_state(open_apero_msgs/RobotState, the same two poses) while executing a command and, until the first one, the initial pose, whichdummy_controller_noderepeats every 0.1 s. Each message counts as the outcome of the latest command.Pose with
use_tf: true(for an asynchronous robot): publish TFmap_frame→base_frameandmap_frame→camera_frame, and after each command one/command/result(open_apero_msgs/CommandResult) with itscommand_sequence,header.frame_id=map_frameand the final state. TF alone never completes a command.Point clouds: publish
/open_apero_camera/point_cloud(sensor_msgs/PointCloud2incamera_optical_frame) and/camera_transform(geometry_msgs/TransformStamped, that frame inmap_frame) with identical stamps, or setvoxblox_node’suse_tf_transformstotrueand remap itspointcloudinput to the robot’s cloud. Give pixels with no return as points beyondray_length, like Habitat’sfar_depth_sentinel: only these clear free space along rays that hit nothing.
A command is done once the sensor pose is within target_position_threshold (0.10 m) and target_angle_threshold
(0.20 rad) of its last state and, with wait_for_map_updated: true, a cloud taken there in the optical frame of
camera_frame is mapped (The Settle Gate). For a cloud in another frame, such as
a LiDAR’s, set wait_for_map_updated: false; for a robot that cannot track within the thresholds, raise them. Poses
with a non-unit quaternion are dropped. Of a RobotState on /robot_state or /command/result, the planner keeps the
camera pose, roll zeroed, and re-derives the base from it through the robot model’s sensor mount.
Adapt the Configuration#
robotinconfig/planners/_common.yaml: velocity limits, collision spheres,sample_z: falsefor a ground robot and, withuse_tf: false, the sensor mount (Robot Models)./map_bounding_volume(where the robot may plan) and/target_bounding_volume(where gain counts), boxes inmap_frame(Configuration Files).sensor_modelinconfig/tasks/_common.yaml: the camera’s resolution and focal length. A LiDAR takesIterativeRayCasterLidar, which is spherical: give itresolution_x/_y(rays) andfield_of_view_x/_y[deg] instead offocal_lengthandobservation_boundary, and drop the launch’ssensor_model/observation_boundaryparam, or they are reported unread (Sensor Models). The launch argumentsray_lengthandobservation_boundaryset the camera’s range andvoxblox_node’s; set them to what the robot’s map integrates with.
Start and Stop#
The coordinator creates the run directory, sets the planner’s ~run_dir and runs it until time_limit minutes pass or
a message arrives on /open_apero/collision (std_msgs/String), the hook for a bumper or safety node. To start the
planner by hand, give it an existing, empty run directory first, which it requires with log_data:=true (default):
mkdir -p ~/open_apero_data/my_robot/run_01
rosparam set /open_apero_node/run_dir ~/open_apero_data/my_robot/run_01
rosservice call /open_apero_node/toggle_running "data: true" # false stops, writes the summary
The open_apero_node reference
lists every topic, service and parameter. A platform without ROS derives its own agent from Agent and implements
sendMovement() and publishVisualization() (The Loop).