Automated CI/CD testing platform for robot waypoint navigation with Jenkins orchestration, Docker containerization, and Google Test validation.
WaypointCI is a production-ready continuous integration platform designed specifically for validating autonomous robot navigation systems in ROS2 Galactic. The platform automatically builds, tests, and validates waypoint navigation capabilities through a custom action server implementation whenever code changes are pushed to the repository. Built with Google Test for comprehensive unit testing, Docker for reproducible environments, and Jenkins for CI/CD orchestration, the system ensures navigation accuracy through automated validation in Gazebo simulation with real-world physics. The platform achieves sub-5cm position accuracy and π/90 radian orientation precision in automated testing cycles.
┌─────────────────────────────────────────────────────────────────────────┐
│ WaypointCI Testing Pipeline │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ [GitHub Push Event] │
│ ↓ │
│ ┌──────────────┐ Webhook / SCM Polling │
│ │ Code Change │ ─────────────────────────────→ │
│ └──────────────┘ │
│ │
│ ┌────────────────────── JENKINS PIPELINE ──────────────────────┐ │
│ │ │ │
│ │ Stage 1: Environment Verification │ │
│ │ └─→ Workspace check, ROS2 Galactic validation │ │
│ │ │ │
│ │ Stage 2: Docker Infrastructure │ │
│ │ └─→ Container build with ros:galactic base │ │
│ │ │ │
│ │ Stage 3: Simulation Environment │ │
│ │ └─→ Gazebo launch, TortoiseBot spawn, world setup │ │
│ │ │ │
│ │ Stage 4: Action Server Initialization │ │
│ │ └─→ Waypoint action server startup on /tortoisebot_as │ │
│ │ │ │
│ │ Stage 5: Test Execution (Google Test) │ │
│ │ └─→ colcon test --packages-select tortoisebot_waypoints │ │
│ │ │ │
│ │ Stage 6: Validation │ │
│ │ ├─→ Position Test: Target (1,1) within 20cm tolerance │ │
│ │ └─→ Angle Test: Yaw 1.57 rad within 0.5 rad tolerance │ │
│ │ │ │
│ │ Stage 7: Results & Reporting │ │
│ │ └─→ colcon test-result --verbose, JUnit XML output │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
│ [Test Metrics] │
│ • Position Accuracy: ±5cm (actual) vs ±20cm (test threshold) │
│ • Orientation Precision: π/90 rad (actual) vs 0.5 rad (test) │
│ • Execution Time: ~30 seconds per complete test cycle │
│ • Success Rate: 95% (Gazebo timing dependent) │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Step 1: Goal Dispatch Step 2: Navigation Control
┌──────────────────┐ ┌────────────────────┐
│ Send Waypoint │ │ State Machine │
│ Goal (1,1,1.57) │ ────→ │ - Fix yaw │
│ via Action API │ │ - Go to point │
└──────────────────┘ │ - Final rotation │
└────────────────────┘
↓ ↓
Step 3: Real-time Feedback Step 4: Validation
┌──────────────────┐ ┌────────────────────┐
│ Position Update │ │ Google Test │
│ State: "fix yaw"│ │ - Position: ✓ │
│ Current: (x,y) │ │ - Angle: ✓ │
└──────────────────┘ │ BUILD SUCCESS │
└────────────────────┘
[Pipeline] { (Run colcon tests)
Starting >>> tortoisebot_waypoints
--- stderr: tortoisebot_waypoints
[==========] Running 2 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 2 tests from WaypointTesting
[ RUN ] WaypointTesting.CheckPositionValidity
[INFO] [test_node]: Goal accepted!
[INFO] [tortoisebot_as]: Current Yaw: 0.000000
[INFO] [tortoisebot_as]: Fix yaw
[INFO] [tortoisebot_as]: Go to point
Linear error: 0.048 m
[ OK ] WaypointTesting.CheckPositionValidity (12450 ms)
[ RUN ] WaypointTesting.CheckAngleValidity
[INFO] [tortoisebot_as]: Turning at final point
Yaw error: 0.035 rad
[ OK ] WaypointTesting.CheckAngleValidity (8230 ms)
[----------] 2 tests from WaypointTesting (20680 ms total)
[==========] 2 tests from 1 test suite ran. (20680 ms total)
[ PASSED ] 2 tests.
Finished <<< tortoisebot_waypoints [21.2s]
Summary: 1 package finished [21.7s]Live Monitoring: Access Jenkins Dashboard → WaypointCI → Console Output for real-time test execution logs
- Action Server Architecture: Custom ROS2 action server with goal/feedback/result handling
- Three-Phase Navigation: Yaw correction → Linear motion → Final orientation adjustment
- Google Test Integration: Comprehensive unit testing with position and angle validation
- Docker Containerization: Isolated testing environment with reproducible builds
- Gazebo Physics Simulation: Real-world dynamics testing with TortoiseBot model
- Precision Control: 0.2 m/s linear velocity, 0.35 rad/s angular velocity
- Continuous Feedback: Real-time position and state updates during navigation
- Automated CI/CD: GitHub webhook triggers with Jenkins orchestration
| Metric | Value | Conditions |
|---|---|---|
| Position Precision | ±5cm | Controller accuracy |
| Position Test Threshold | ±20cm | Google Test tolerance |
| Orientation Precision | π/90 rad | ~2° accuracy |
| Orientation Test Threshold | 0.5 rad | ~28° tolerance |
| Linear Velocity | 0.2 m/s | Forward motion |
| Angular Velocity | 0.35 rad/s | Rotation speed |
| Test Execution Time | 30 seconds | Full waypoint cycle |
| Build Time | 3-5 minutes | Docker + compilation |
| Success Rate | 95% | Gazebo timing dependent |
- Framework: ROS2 Galactic
- Testing Framework: Google Test (gtest) with colcon
- CI/CD Platform: Jenkins 2.x Pipeline
- Containerization: Docker & Docker Compose
- Simulation: Gazebo 11 with TortoiseBot model
- Action Framework: rclcpp_action for ROS2
- Build System: Colcon with ament_cmake
- Version Control: Git with GitHub webhooks
- Languages: C++ 17 for core implementation
# System requirements
Ubuntu 20.04 or Docker-compatible Linux distribution
Git with SSH authentication configured
# Establish GitHub connection (first time only)
git ls-remote -h -- git@github.com:yourusername/WaypointCI.git HEAD
# Type 'yes' if prompted about authenticity# Clone repository
git clone https://github.com/yourusername/WaypointCI.git
cd WaypointCI
# Start Jenkins server
source ~/.bashrc
cd ~/webpage_ws/ && bash start_jenkins.sh
# Wait for "Jenkins is running in the background"
# Get Jenkins URL
jenkins_address # Click to open in browser
# OR
cat ~/jenkins__pid__url.txtUsername: admin
Password: [your_configured_password]
# Jenkins Dashboard
1. Navigate to "WaypointCI" project
2. Click "Build Now"
3. Monitor in "Build Executor Status"# Trigger CI pipeline
git add .
git commit -m "feat: improve waypoint precision"
git push origin main
# Jenkins automatically detects and builds# Build Docker environment
docker-compose -f docker-compose-build.yml build
# Start containers
docker-compose up -d
# Run tests directly
docker exec tortoisebot-test-ros2 bash -c \
"source install/setup.bash && \
colcon test --packages-select tortoisebot_waypoints \
--event-handler=console_direct+"
# View detailed results
docker exec tortoisebot-test-ros2 bash -c \
"source install/setup.bash && \
colcon test-result --verbose"# Watch odometry updates
ros2 topic echo /odom
# Monitor velocity commands
ros2 topic echo /cmd_vel
# Check action server status
ros2 action list
ros2 action info /tortoisebot_asWaypointCI/
├── tortoisebot_waypoints/ # Core waypoint navigation package
│ ├── CMakeLists.txt # Build configuration with gtest
│ ├── package.xml # Dependencies declaration
│ ├── action/ # Action definitions
│ │ └── WaypointAction.action # Goal: Point, Result: bool, Feedback: Point+state
│ ├── src/ # Source implementation
│ │ └── tortoisebot_action_server.cpp # Three-phase navigation logic
│ └── test/ # Test suite
│ ├── main.cpp # Google Test entry point
│ └── waypoints_ros2_test.cpp # Position & angle validation tests
├── Dockerfile # ROS2 Galactic container definition
├── Jenkinsfile # CI/CD pipeline stages
├── docker-compose.yml # Multi-container orchestration
├── docker-compose-build.yml # Build configuration
├── mybringup.launch.py # Custom launch with waypoint server
└── test_trigger.txt # SCM change trigger file
class WaypointActionClass : public rclcpp::Node {
// Three-phase navigation state machine
States: "fix yaw" → "go to point" → "turning at final point"
// Precision thresholds
Position: 0.05m (5cm)
Orientation: π/90 rad (~2°)
// Control outputs
Linear velocity: 0.2 m/s
Angular velocity: ±0.35 rad/s
}- Initial Yaw Correction: Align robot heading toward target
- Linear Navigation: Move toward waypoint with minor yaw adjustments
- Final Orientation: Rotate to desired final heading
- Feedback Loop: Continuous odometry updates at 25Hz
TEST_F(WaypointTesting, CheckPositionValidity) {
// Send goal: (1.0, 1.0, 1.57)
// Wait for action completion
// Validate: linear_error < 0.2m
}
TEST_F(WaypointTesting, CheckAngleValidity) {
// Same goal execution
// Validate: yaw_error <= 0.5 rad
}- Base Image: ros:galactic for consistency
- Dependencies: Pre-installed ROS2 packages
- Workspace: /ros2_ws with source code
- Networking: Bridge network for container communication
- Volumes: X11 forwarding for Gazebo GUI
- Environment Check: Verify workspace and ROS2 setup
- Docker Install: Ensure container runtime availability
- Container Launch: docker-compose up with services
- Service Ready: Wait for container initialization
- Test Execution: colcon test with Google Test
- Result Parse: Extract and display test outcomes
- Cleanup: Container teardown and workspace reset
-
Action server not available:
# Increase timeout in test setup action_test_client->wait_for_action_server(20s) # Verify server is running ros2 action list
-
Gazebo timing issues:
# Add delay after world spawn sleep 5 # In Jenkinsfile # Or increase test timeout
-
Position test failures:
# Check odometry publishing rate ros2 topic hz /odom # Verify cmd_vel is being received ros2 topic echo /cmd_vel
-
Docker build failures:
# Clear Docker cache docker system prune -a # Rebuild from scratch docker-compose build --no-cache
- Test Isolation: Each test run starts with clean state
- Timeout Management: Prevents hanging builds (30s limit)
- Verbose Logging: Detailed output for debugging
- Modular Testing: Separate position and angle validation
- Configurable Thresholds: Easy tuning of tolerances
- Automated Triggers: GitHub webhook integration
- Container Caching: Faster rebuilds with layer optimization
// Modify in waypoints_ros2_test.cpp
this->goal_point.x = 2.0; // Change target position
this->goal_point.y = 2.0;
this->goal_point.z = 3.14; // Change target orientation// In tortoisebot_action_server.cpp
const auto d_precision = 0.02; // Tighter position tolerance
const auto y_precision = M_PI / 180; // 1° orientation precision- Multi-waypoint trajectory testing
- Obstacle avoidance validation
- Performance benchmarking suite
- Code coverage reporting with gcov
- Parallel test execution
- Hardware-in-loop testing
- ROS2 Humble migration
- Kubernetes deployment
Pull requests are welcome. Please ensure all tests pass before submitting.
Educational project for robotics CI/CD demonstration. License TBD.
Ritwik Rohan
Robotics Engineer | Johns Hopkins MSE '25
Email: ritwikrohan7@gmail.com
LinkedIn: linkedin.com/in/ritwik-rohan