Skip to content

Commit 89fa0b0

Browse files
authored
Refactor perception and integrate costmap, planner, and control modules (#39)
* refactor perception and integrate costmap, planner, and control modules * Update readme * Change demo video to link * add demo screenshot * Add demo screenshot to README * commit pre-commit changes * Add demo video as github embed * Update yamllint config * fix cpp pre-commit hook issues
1 parent 98ed3da commit 89fa0b0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+4817
-648
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@ __pycache__
66
watod-config.local.sh
77
**/.DS_Store
88
draft_*
9+
*copy*
10+
camera-info.txt
11+
src/gazebo/launch/MR24-DT-A00.00 - URDF/

README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,62 @@ These steps are to setup the repo to work on your own PC. We utilize docker to e
88
1. This repo is supported on Linux Ubuntu >= 22.04, Windows (WSL), and MacOS. This is standard practice that roboticists can't get around. To setup, you can either setup an [Ubuntu Virtual Machine](https://ubuntu.com/tutorials/how-to-run-ubuntu-desktop-on-a-virtual-machine-using-virtualbox#1-overview), setting up [WSL](https://learn.microsoft.com/en-us/windows/wsl/install), or setting up your computer to [dual boot](https://opensource.com/article/18/5/dual-boot-linux). You can find online resources for all three approaches.
99
2. Once inside Linux, [Download Docker Engine using the `apt` repository](https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository)
1010
3. You're all set! You can visit the [WATO Wiki](https://wiki.watonomous.ca/autonomous_software_general/monorepo_infrastructure) for more documentation on the WATO infrastructure.
11+
12+
## Demo
13+
https://github.com/user-attachments/assets/d4e821cd-8db7-4176-9e2e-1d9c62aab23d
14+
15+
![Demo Screenshot](assets/demos/demo_nov30.png)
16+
17+
## Simulation Environment
18+
19+
We use Ignition Gazebo for physics simulation. The main world file is `robot_env.sdf`, which defines the entire simulation scene.
20+
21+
### Robot Model (SDF)
22+
A basic model of the rover is defined directly in the SDF with a differential drive base. Key components:
23+
- **Chassis**: 2.0m x 1.0m x 0.5m box with inertial properties
24+
- **Wheels**: Four cylindrical wheels with revolute joints
25+
- **IMU**: Mounted on chassis, publishes to `/imu`
26+
- **RGBD Camera**: Simulated RealSense D435 mounted on the front
27+
28+
### Depth Camera Simulation
29+
The depth camera is configured as an `rgbd_camera` sensor with realistic FOV, intrinsics, etc.
30+
31+
It publishes:
32+
- `/camera/image` ([Image](https://docs.ros.org/en/noetic/api/sensor_msgs/html/msg/Image.html)) - RGB image (used by YOLO object detector)
33+
- `/camera/points` ([PointCloud2](https://docs.ros.org/en/noetic/api/sensor_msgs/html/msg/PointCloud2.html)) - 3D point cloud (used by costmap)
34+
35+
### Mars Environment (URDF)
36+
The environment is loaded from `mars_env.urdf`, which includes meshes for the mars terrain, mallet, and water bottle.
37+
38+
The terrain has collision geometry so the rover can't drive through obstacles.
39+
40+
### ROS2 Bridge
41+
The `ros_gz_bridge` translates Ignition messages to ROS2 topics, bridging `/cmd_vel`, `/imu`, camera streams, and TF transforms. This way, our ROS2 autonomy stack interface seamlessly with the Gazebo sim.
42+
43+
## Autonomy Architecture
44+
45+
### Sensor Simulation
46+
- **gps_sim**: Simulates GPS measurements by reading ground truth transforms from the simulator and injecting realistic noise and dropouts. Publishes [NavSatFix](https://docs.ros.org/en/kinetic/api/sensor_msgs/html/msg/NavSatFix.html) messages.
47+
- **imu_sim**: Adds sensor noise and bias to clean IMU data to mimic real-world sensors. Takes ground truth IMU and outputs noisy orientation and angular velocity.
48+
49+
### Localization
50+
- **localization**: Runs an Extended Kalman Filter (EKF) to fuse (simulated) noisy GPS and IMU data into a smooth, filtered odometry estimate. Outputs robot pose for downstream modules.
51+
52+
### Perception & Mapping
53+
- **costmap**: Converts RGBD camera point clouds into a local 2D occupancy grid centered on the robot. Marks obstacles and inflates them for safety margins.
54+
- **map_memory**: Stitches together local costmaps into a persistent global map as the rover explores. Only updates when the robot moves beyond a threshold distance to reduce computational load.
55+
- **yolo_inference**: Runs YOLOv8 object detection (ONNX runtime) on camera images to detect objects like bottles and mallets. Publishes annotated images with bounding boxes.
56+
57+
### Planning & Control
58+
- **planner**: Implements A* search on the global occupancy grid. Takes the current robot pose and a goal point, outputs a collision-free path. Replans when new goals arrive.
59+
- **control**: Pure pursuit controller that tracks the planned path. Uses a PID loop (configurable Kp, Ki, Kd gains) to compute steering corrections based on cross-track error. Outputs angular velocity to steer toward the target waypoint while maintaining constant forward velocity, publishing [Twist](https://docs.ros.org/en/jade/api/geometry_msgs/html/msg/Twist.html) commands to `/cmd_vel`.
60+
61+
### Data Flow
62+
The pipeline runs as follows:
63+
- Sensor sims generate noisy data
64+
- Localization fuses it into an estimate of the robot's position (odometry)
65+
- Costmap builds local obstacles
66+
- Map memory accumulates into global map
67+
- Planner finds path to goal
68+
- Control executes path
69+
- Motor commands actuate the rover

assets/demos/demo_nov30.mp4

62.8 MB
Binary file not shown.

assets/demos/demo_nov30.png

1.49 MB
Loading

docker/gazebo/gazeboserver.Dockerfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ RUN apt-get update && apt-get install -y --no-install-recommends curl \
1515
# Scan for rosdeps
1616
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
1717
RUN apt-get -qq update && rosdep update && \
18-
(rosdep install --from-paths . --ignore-src -r -s \
19-
| grep 'apt-get install' \
18+
(rosdep install --from-paths . --ignore-src -r -s || true) \
19+
| (grep 'apt-get install' || true) \
2020
| awk '{print $3}' \
21-
| sort > /tmp/colcon_install_list || echo "# No additional dependencies needed" > /tmp/colcon_install_list)
21+
| sort > /tmp/colcon_install_list
2222

2323
################################# Dependencies ################################
2424
FROM ${BASE_IMAGE} AS dependencies

docker/robot/robot.Dockerfile

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,25 @@ RUN apt-get update && apt-get install -y --no-install-recommends curl \
1010
&& rm -rf /var/lib/apt/lists/*
1111

1212
# Copy in source code
13-
COPY src/robot/yolo_inference ./yolo_inference
14-
COPY src/robot/object_detection object_detection
13+
# COPY src/robot/yolo_inference ./yolo_inference
14+
# COPY src/robot/object_detection object_detection
1515
COPY src/robot/odometry_spoof odometry_spoof
16+
COPY src/robot/gps_sim gps_sim
17+
COPY src/robot/imu_sim imu_sim
18+
COPY src/robot/localization localization
19+
COPY src/robot/costmap costmap
20+
COPY src/robot/map_memory map_memory
21+
COPY src/robot/planner planner
22+
COPY src/robot/control control
1623
COPY src/robot/bringup_robot bringup_robot
17-
COPY src/robot/camera_fallback camera_fallback
18-
COPY src/robot/arcade_driver arcade_driver
19-
COPY src/robot/motor_speed_controller motor_speed_controller
20-
COPY src/wato_msgs/drivetrain_msgs drivetrain_msgs
2124

2225
# Scan for rosdeps
2326
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
2427
RUN apt-get -qq update && rosdep update && \
25-
(rosdep install --from-paths . --ignore-src -r -s \
26-
| grep 'apt-get install' \
27-
| awk '{print $3}' \
28-
| sort > /tmp/colcon_install_list || echo "# No additional dependencies needed" > /tmp/colcon_install_list)
28+
(rosdep install --from-paths . --ignore-src -r -s || true) \
29+
| (grep 'apt-get install' || true) \
30+
| awk '{print $3}' \
31+
| sort > /tmp/colcon_install_list || echo "# No additional dependencies needed" > /tmp/colcon_install_list
2932

3033
################################# Dependencies ################################
3134
FROM ${BASE_IMAGE} AS dependencies
@@ -50,8 +53,8 @@ RUN apt-get -qq update && \
5053
rm -rf /var/lib/apt/lists/*
5154

5255
# Copy in source code from source stage
53-
WORKDIR ${AMENT_WS}/src
54-
COPY src/robot/object_detection object_detection
56+
# WORKDIR ${AMENT_WS}/src
57+
# COPY src/robot/object_detection object_detection
5558
WORKDIR ${AMENT_WS}
5659
COPY --from=source ${AMENT_WS}/src src
5760

docker/vis_tools/foxglove.Dockerfile

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ RUN apt-get update && apt-get install -y --no-install-recommends curl \
1515
# Scan for rosdeps
1616
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
1717
RUN apt-get -qq update && rosdep update && \
18-
(rosdep install --from-paths . --ignore-src -r -s \
19-
| grep 'apt-get install' \
18+
(rosdep install --from-paths . --ignore-src -r -s || true) \
19+
| (grep 'apt-get install' || true) \
2020
| awk '{print $3}' \
21-
| sort > /tmp/colcon_install_list || echo "# No additional dependencies needed" > /tmp/colcon_install_list)
21+
| sort > /tmp/colcon_install_list
2222

2323
################################# Dependencies ################################
2424
FROM ${BASE_IMAGE} AS dependencies
@@ -36,7 +36,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends lsb-release sof
3636
apt-add-repository universe && \
3737
rm -rf /var/lib/apt/lists/*
3838

39-
# Install Dependencies
4039
# Install Dependencies
4140
RUN apt-get update && \
4241
apt-get install -y --no-install-recommends \
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
commit 0bb5293d52599317a3e300c55897e34a48e5e289
2+
Author: Barry Zhang <45883553+bluebarryz@users.noreply.github.com>
3+
Date: Wed Jan 7 19:46:46 2026 -0500
4+
5+
refactor perception and integrate costmap, planner, and control modules
6+
7+
.gitignore | 3 +
8+
docker/gazebo/gazeboserver.Dockerfile | 10 +-
9+
docker/robot/robot.Dockerfile | 29 +-
10+
docker/vis_tools/foxglove.Dockerfile | 11 +-
11+
modules/docker-compose.robot.yaml | 13 +-
12+
src/gazebo/launch/env.urdf | 357 ++++++-----
13+
src/gazebo/launch/mr24/robot.urdf | 365 +++++++++++
14+
src/gazebo/launch/robot_env.sdf | 668 +++++++++------------
15+
src/gazebo/launch/sim.launch.py | 60 +-
16+
src/robot/bringup_robot/launch/robot.launch.py | 206 +++++--
17+
src/robot/bringup_robot/package.xml | 14 +-
18+
src/robot/control/CMakeLists.txt | 7 +-
19+
src/robot/control/config/params.yaml | 14 +-
20+
src/robot/control/include/control_core.hpp | 47 ++
21+
src/robot/control/include/control_node.hpp | 63 ++
22+
src/robot/control/package.xml | 3 +
23+
src/robot/control/src/control_core.cpp | 146 ++++-
24+
src/robot/control/src/control_node.cpp | 101 +++-
25+
src/robot/costmap/CMakeLists.txt | 5 +-
26+
src/robot/costmap/config/params.yaml | 20 +-
27+
src/robot/costmap/include/costmap_core.hpp | 50 ++
28+
src/robot/costmap/include/costmap_node.hpp | 46 ++
29+
src/robot/costmap/package.xml | 3 +
30+
src/robot/costmap/src/costmap_core.cpp | 170 +++++-
31+
src/robot/costmap/src/costmap_node.cpp | 88 ++-
32+
src/robot/gps_sim/CMakeLists.txt | 47 ++
33+
src/robot/gps_sim/config/params.yaml | 13 +
34+
src/robot/gps_sim/include/gps_sim_node.hpp | 46 ++
35+
src/robot/gps_sim/package.xml | 28 +
36+
src/robot/gps_sim/src/gps_sim_node.cpp | 134 +++++
37+
src/robot/imu_sim/CMakeLists.txt | 41 ++
38+
src/robot/imu_sim/config/params.yaml | 18 +
39+
src/robot/imu_sim/include/imu_sim_node.hpp | 53 ++
40+
src/robot/imu_sim/package.xml | 25 +
41+
src/robot/imu_sim/src/imu_sim_node.cpp | 171 ++++++
42+
src/robot/localization/CMakeLists.txt | 56 ++
43+
src/robot/localization/config/params.yaml | 25 +
44+
.../localization/include/localization_core.hpp | 106 ++++
45+
.../localization/include/localization_node.hpp | 73 +++
46+
src/robot/localization/package.xml | 29 +
47+
src/robot/localization/src/localization_core.cpp | 501 ++++++++++++++++
48+
src/robot/localization/src/localization_node.cpp | 225 +++++++
49+
src/robot/map_memory/CMakeLists.txt | 8 +-
50+
src/robot/map_memory/config/params.yaml | 26 +-
51+
src/robot/map_memory/include/map_memory_core.hpp | 38 ++
52+
src/robot/map_memory/include/map_memory_node.hpp | 63 ++
53+
src/robot/map_memory/package.xml | 3 +
54+
src/robot/map_memory/src/map_memory_core.cpp | 110 +++-
55+
src/robot/map_memory/src/map_memory_node.cpp | 141 ++++-
56+
.../odometry_spoof/include/odometry_spoof.hpp | 40 ++
57+
src/robot/odometry_spoof/src/odometry_spoof.cpp | 92 +--
58+
src/robot/planner/CMakeLists.txt | 4 +-
59+
src/robot/planner/config/params.yaml | 16 +-
60+
src/robot/planner/include/planner_core.hpp | 125 +++-
61+
src/robot/planner/include/planner_node.hpp | 70 ++-
62+
src/robot/planner/package.xml | 2 +
63+
src/robot/planner/src/planner_core.cpp | 262 +++++++-
64+
src/robot/planner/src/planner_node.cpp | 186 +++++-
65+
58 files changed, 4503 insertions(+), 773 deletions(-)

modules/docker-compose.robot.yaml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,6 @@ services:
1212
profiles:
1313
- deploy
1414
command: /bin/bash -c "ros2 launch bringup_robot robot.launch.py"
15-
devices:
16-
- /dev/bus/usb:/dev/bus/usb
17-
volumes:
18-
- /dev:/dev
19-
privileged: true
2015

2116
robot_dev:
2217
build: *robot_build
@@ -26,7 +21,3 @@ services:
2621
- develop
2722
volumes:
2823
- ${MONO_DIR}/src/robot:/root/ament_ws/src
29-
- /dev:/dev
30-
devices:
31-
- /dev/bus/usb:/dev/bus/usb
32-
privileged: true

0 commit comments

Comments
 (0)