Skip to main content

Sensor Simulation: Lidar, Depth, IMU

Learning Objectives

After completing this chapter, you will be able to:

  • Configure and integrate simulated sensors in Gazebo
  • Set up lidar, depth camera, and IMU sensors for humanoid robots
  • Process simulated sensor data in ROS 2
  • Validate sensor accuracy and performance in simulation

Introduction

Sensor simulation is critical for developing and testing perception systems in robotics, allowing developers to create robust algorithms without the constraints and risks of physical hardware. In Physical AI & Humanoid Robotics applications, simulated sensors must closely match their real-world counterparts to ensure that algorithms trained in simulation can transfer effectively to physical robots.

Gazebo provides high-quality simulation of various sensor types, including lidar, depth cameras, and IMUs, which are essential for humanoid robot perception. These sensors enable robots to understand their environment, localize themselves, and interact with objects. Properly configured sensor simulation allows for the development of perception algorithms that can later be deployed on real hardware with minimal adjustments.

Core Concepts

Simulated sensors in Gazebo operate by generating synthetic data based on the virtual environment, mimicking the behavior of real sensors. This involves ray tracing for lidar and depth sensors, and mathematical models for IMUs and other inertial sensors.

Sensor Types in Gazebo

Gazebo supports a wide range of sensor types:

  • Ray/Lidar Sensors: Simulate time-of-flight sensors with configurable resolution and range
  • Depth Cameras: Generate depth maps in addition to RGB images
  • IMU Sensors: Simulate accelerometers and gyroscopes with noise models
  • GPS Sensors: Provide position estimates in world coordinates
  • Force/Torque Sensors: Measure forces and torques at joints

Sensor Integration with ROS 2

The gazebo_ros_pkgs provide plugins to bridge Gazebo sensors with ROS 2 topics, allowing simulated sensor data to be processed by the same ROS 2 nodes that would handle real sensor data. This seamless integration is key to the sim-to-real transfer approach.

Noise Modeling

Real sensors include various sources of noise and inaccuracies. Gazebo allows modeling of sensor noise, bias, and drift, making the simulation more realistic and improving the robustness of algorithms developed in simulation.

Hands-on Examples

Let's implement sensor simulation in Gazebo:

<?xml version="1.0"?>
<robot name="sensor_humanoid">
<!-- Base link -->
<link name="base_link">
<inertial>
<mass value="1"/>
<inertia ixx="0.01" ixy="0" ixz="0" iyy="0.01" iyz="0" izz="0.01"/>
</inertial>
</link>

<!-- Torso -->
<joint name="base_to_torso" type="fixed">
<parent link="base_link"/>
<child link="torso"/>
<origin xyz="0 0 0.15"/>
</joint>

<link name="torso">
<visual>
<geometry>
<box size="0.3 0.2 0.5"/>
</geometry>
<material name="grey">
<color rgba="0.5 0.5 0.5 1"/>
</material>
</visual>
<collision>
<geometry>
<box size="0.3 0.2 0.5"/>
</geometry>
</collision>
<inertial>
<mass value="15"/>
<inertia ixx="0.2" ixy="0" ixz="0" iyy="0.2" iyz="0" izz="0.2"/>
</inertial>
</link>

<!-- Head with sensors -->
<joint name="torso_to_head" type="revolute">
<parent link="torso"/>
<child link="head"/>
<origin xyz="0 0 0.4"/>
<axis xyz="0 1 0"/>
<limit lower="-1.57" upper="1.57" effort="10" velocity="1"/>
</joint>

<link name="head">
<visual>
<geometry>
<sphere radius="0.1"/>
</geometry>
<material name="white">
<color rgba="1 1 1 1"/>
</material>
</visual>
<collision>
<geometry>
<sphere radius="0.1"/>
</geometry>
</collision>
<inertial>
<mass value="2"/>
<inertia ixx="0.01" ixy="0" ixz="0" iyy="0.01" iyz="0" izz="0.01"/>
</inertial>
</link>

<!-- Sensors defined in the URDF using Gazebo plugins -->

<!-- IMU sensor in the torso -->
<gazebo reference="torso">
<sensor name="torso_imu" type="imu">
<always_on>true</always_on>
<update_rate>100</update_rate>
<imu>
<angular_velocity>
<x>
<noise type="gaussian">
<mean>0.0</mean>
<stddev>2e-4</stddev>
</noise>
</x>
<y>
<noise type="gaussian">
<mean>0.0</mean>
<stddev>2e-4</stddev>
</noise>
</y>
<z>
<noise type="gaussian">
<mean>0.0</mean>
<stddev>2e-4</stddev>
</noise>
</z>
</angular_velocity>
<linear_acceleration>
<x>
<noise type="gaussian">
<mean>0.0</mean>
<stddev>1.7e-2</stddev>
</noise>
</x>
<y>
<noise type="gaussian">
<mean>0.0</mean>
<stddev>1.7e-2</stddev>
</noise>
</y>
<z>
<noise type="gaussian">
<mean>0.0</mean>
<stddev>1.7e-2</stddev>
</noise>
</z>
</linear_acceleration>
</imu>
</sensor>
</gazebo>

<!-- Depth camera in the head -->
<gazebo reference="head">
<sensor name="head_depth_camera" type="depth">
<always_on>true</always_on>
<update_rate>30</update_rate>
<camera>
<horizontal_fov>1.047</horizontal_fov> <!-- 60 degrees -->
<image>
<format>R8G8B8</format>
<width>640</width>
<height>480</height>
</image>
<clip>
<near>0.1</near>
<far>10</far>
</clip>
</camera>
<plugin name="camera_controller" filename="libgazebo_ros_camera.so">
<frame_name>head</frame_name>
<min_depth>0.1</min_depth>
<max_depth>10.0</max_depth>
</plugin>
</sensor>
</gazebo>

<!-- 360-degree lidar on the head -->
<gazebo reference="head">
<sensor name="head_lidar" type="ray">
<ray>
<scan>
<horizontal>
<samples>360</samples>
<resolution>1</resolution>
<min_angle>-3.14159</min_angle> <!-- -π radians -->
<max_angle>3.14159</max_angle> <!-- π radians -->
</horizontal>
</scan>
<range>
<min>0.1</min>
<max>10</max>
<resolution>0.01</resolution>
</range>
</ray>
<plugin name="lidar_controller" filename="libgazebo_ros_laser.so">
<frame_name>head</frame_name>
<topic_name>scan</topic_name>
</plugin>
<always_on>true</always_on>
<update_rate>10</update_rate>
</sensor>
</gazebo>

<!-- Front-facing RGB camera -->
<gazebo reference="head">
<sensor name="head_camera" type="camera">
<always_on>true</always_on>
<update_rate>30</update_rate>
<camera>
<horizontal_fov>1.047</horizontal_fov>
<image>
<format>R8G8B8</format>
<width>640</width>
<height>480</height>
</image>
<clip>
<near>0.1</near>
<far>10</far>
</clip>
</camera>
<plugin name="rgb_camera_controller" filename="libgazebo_ros_camera.so">
<frame_name>head</frame_name>
</plugin>
</sensor>
</gazebo>

<!-- Gazebo plugin for ROS control -->
<gazebo>
<plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
<robotNamespace>/sensor_humanoid</robotNamespace>
</plugin>
</gazebo>

</robot>

Expected Output:

[INFO] [1678882844.123456789] [sensor_processing_node]: Sensor Processing Node initialized
[INFO] [1678882844.123456789] [sensor_processing_node]: Processed camera image: 640x480
[INFO] [1678882844.123456789] [sensor_processing_node]: Depth: avg=2.45m, min=0.15m, max=9.80m
[INFO] [1678882844.123456789] [sensor_processing_node]: Depth: 12 close, 45 mid, 200 far objects
[INFO] [1678882844.123456789] [sensor_processing_node]: IMU: Roll=0.012, Pitch=-0.008, Yaw=0.003
[INFO] [1678882844.123456789] [sensor_processing_node]: Lidar: Closest obstacle at 1.25m
[INFO] [1678882844.123456789] [sensor_fusion_node]: Sensor Fusion Node initialized
[INFO] [1678882844.123456789] [sensor_fusion_node]: Fused State: Pos (0.00, 0.00, 0.00), Vel (0.00, 0.00, 0.00)

Exercises

Complete the following exercises to reinforce your understanding:

  1. Sensor Fusion: Implement a more sophisticated sensor fusion algorithm

    • Combine lidar and IMU data for improved position estimation
    • Implement a Kalman filter for sensor fusion
    • Test how the fused data improves navigation performance
    • Compare fused estimates to ground truth
  2. Obstacle Detection: Develop a comprehensive obstacle detection system

    • Use multiple sensors to detect and map obstacles
    • Create a navigation costmap from sensor data
    • Implement path planning based on sensor data
    • Validate the system in complex environments

Common Pitfalls and Solutions

  • Pitfall 1: Noise in sensor data - Raw sensor data contains noise that affects processing
    • Solution: Implement filtering and outlier detection algorithms
  • Pitfall 2: Sensor synchronization - Data from different sensors arrives at different times
    • Solution: Implement time synchronization and interpolation techniques
  • Pitfall 3: Coordinate frame mismatches - Sensors in different frame of references
    • Solution: Use TF transforms to properly align sensor data
  • Pitfall 4: Performance issues - Processing multiple sensors in real-time
    • Solution: Optimize algorithms and reduce sensor update rates where appropriate

Summary

  • Sensor simulation enables development of perception algorithms without physical hardware
  • Gazebo supports various sensor types with realistic models
  • ROS 2 integration allows seamless processing of simulated sensor data
  • Sensor fusion combines data from multiple sources for improved estimates
  • Proper noise modeling ensures algorithms work in real scenarios

Further Reading