Skip to content

Sensors ​

A sensor is a part placed like any other; its component type says what the targets simulate and what navigation does with its data.

TypePublishesFeeds
Lidar/scanThe costmaps and the localizer
Lidar3D/lidar3d/points, its middle ring on /lidar3d/scanThe costmaps; the ring stands in for a laser
DepthCamera/depth/image_raw, /depth/pointsThe costmaps; a scan made from its cloud stands in for a laser
RGBD/rgbd/image_raw, /rgbd/depth/image_raw, /rgbd/points, /rgbd/camera_infoAs for a depth camera
Camera/camera/image_raw, /camera/camera_infoNothing; the images are yours
IMU/imuNothing; the readings are yours
Ultrasonic/ultrasonic/rangeThe costmaps' range layer
Range/rangeThe costmaps' range layer
Bumper/bumper, the contacts it feelsCheck_contact

The first sensor of a type gets these topics; a second one of the same type is suffixed with its component name. Each sensor's frame is its component name.

Which sensor navigation uses ​

Nav2's costmaps mark what every point cloud sees, between 0.05 and 2 m above the ground. The costmaps and the localizer also read one planar scan, chosen in this order:

  1. the first Lidar;
  2. the middle ring of the first Lidar3D;
  3. a scan made from the first depth or RGBD camera's cloud, projected onto the ground plane.

A range finder's reading marks the costmaps' range layer. A robot with no range sensor at all is warned that it navigates blind.

Range finders ​

Ultrasonic measures with sound, Range with light: an infrared triangulation sensor or a time-of-flight one. Both report the nearest thing in a narrow cone along their +x, as sensor_msgs/Range, and differ in what the floor does. A sound pulse glancing off the floor does not come back, so an ultrasonic sensor's floor returns are dropped. Light does come back from a matte floor, so a Range sensor reads the floor wherever its cone meets it within its range, and the costmaps then mark the floor as an obstacle. The rule sensing.range_clears_the_ground warns about such a sensor at compile time and says how far to tilt it up, or how high to mount it.

A Range part states what it measures, from its maker's datasheet, in a range block: min_m, max_m, field_of_view_rad and rate_hz. A sensor that says only whether something is within one distance states that distance as both min_m and max_m; it reports -inf when something is there and +inf when nothing is, as sensor_msgs/Range defines it, and the range layer marks or clears its cone. An Ultrasonic part may state a range block too.

Specifications the targets fill in ​

Except for a range finder's range block, a library part does not yet state a sensor's specification: its range, beam count, field of view or rate. Until it does, the targets use these, and declare each one in compile.json:

TypeSimulated as
Lidar360 beams over the full circle, 0.3 to 12 m, 10 Hz
Lidar3D16 rings of 360 beams over 0.52 rad, 0.3 to 20 m, 10 Hz
Camera320 by 240 pixels, 1.089 rad field of view, 10 Hz
DepthCamera, RGBD160 by 120 pixels, 1.089 rad field of view, depth 0.1 to 5 m, 10 Hz
IMUIdeal, 100 Hz
UltrasonicA cone of 9 by 9 beams, 0.52 rad, 0.02 to 4 m, 20 Hz unless the part states its own; the nearest return more than 0.05 m above the ground is the reading
RangeA cone of 9 by 9 beams over the part's stated cone, range and rate; the nearest return is the reading, the floor included
BumperAn ideal contact switch over its collision box, 50 Hz

Mounting ​

A sensor looks along its own +x. The connector it is glued to, of the chassis or of a part placed on it, together with the connector's up, decides which way that points on the robot; the TF tree carries the result, so a sensor mounted upside down still reports correctly in its own frame.