5. Robot Simulation with Gazebo & Unity
Robot simulation is a critical tool in robotics development, allowing engineers to test algorithms, design robots, and develop control strategies in a safe, cost-effective, and reproducible virtual environment. This chapter explores two popular simulation platforms: Gazebo and Unity.
Gazebo
Gazebo is a powerful open-source 3D robot simulator. It accurately simulates rigid body dynamics, sensors (cameras, LIDAR, force sensors), and provides a robust physics engine. It integrates seamlessly with ROS 2, making it a go-to choice for academic and research robotics.
Unity
Unity is a versatile real-time 3D development platform primarily known for game development, but increasingly used in robotics. Its powerful rendering capabilities, asset store, and C# scripting make it suitable for simulating complex environments and human-robot interaction, especially for visually rich scenarios.
Why Simulate?
- Safety: Test hazardous scenarios without risk to physical hardware or humans.
- Cost-Effectiveness: Reduce hardware damage and development costs.
- Reproducibility: Easily reset and rerun experiments.
- Acceleration: Test algorithms faster than on real hardware.
Conceptual Simulation Loop (Simplified)
class Simulator:
def __init__(self, robot_model, environment_model):
self.robot = robot_model
self.environment = environment_model
self.time = 0.0
self.dt = 0.01 # Time step
def update(self):
# 1. Sense: Get sensor data from simulated environment
sensor_data = self.robot.sense(self.environment)
# 2. Plan: Robot decides next action based on sensor data
command = self.robot.plan(sensor_data)
# 3. Act: Robot executes action in simulated environment
self.robot.act(command, self.environment, self.dt)
# Update simulation time
self.time += self.dt
def run(self, duration):
while self.time < duration:
self.update()
# print(f"Sim Time: {self.time:.2f}")
# Mock Robot and Environment for conceptual simulation
class MockRobot:
def sense(self, env):
# Simulate reading from environment
return {"distance": env.get_obstacle_distance()}
def plan(self, sensor_data):
if sensor_data["distance"] < 1.0:
return {"action": "turn"}
else:
return {"action": "move_forward"}
def act(self, command, env, dt):
if command["action"] == "turn":
# Simulate turning
pass
elif command["action"] == "move_forward":
# Simulate moving
pass
env.update_robot_position(self, command["action"], dt)
class MockEnvironment:
def __init__(self):
self.obstacle_distance = 10.0 # Initial distance
def get_obstacle_distance(self):
# Simulate obstacle moving closer
self.obstacle_distance = max(0.5, self.obstacle_distance - 0.1)
return self.obstacle_distance
def update_robot_position(self, robot, action, dt):
pass
if __name__ == "__main__":
robot = MockRobot()
environment = MockEnvironment()
simulator = Simulator(robot, environment)
simulator.run(5.0) # Run simulation for 5 seconds
print("Simulation finished.")