Skip to content

Conversation

@ecourtois
Copy link
Contributor

This PR introduces a Virtual Camera system, allowing the robot to "see" the virtual table in the Monitor. This is a major step towards full-stack simulation. It also integrates Eurobot 2026 rules and improves camera calibration.

🎮 Virtual Camera & Simulation ### (Major)

  • Virtual Camera Support: The Monitor now generates a video stream based on the virtual robot's position on the table.
  • Live View: Added support for displaying the camera stream (real or virtual) directly in the Monitor interface.
  • Full Simulation Loop: The robotcam service can now consume this virtual stream, allowing the entire vision and localization stack to run without physical hardware.

🎨 Monitor (Eurobot 2026)

  • Added 2026 table background and game elements (Granary, Crates, Thermometers).
  • Cleaned up 2025-specific code.

📷 Vision & Calibration

  • 6DOF Calibration: Implemented full 3D calibration (x, y, z, roll, pitch, yaw) for precise camera positioning.
  • Global Shutter Support: Optimized Aruco parameters for the new RPI Global Shutter camera.

✅ Verification

  • 6DOF calibration validated.- Simulation: The robot successfully localizes itself on the virtual table using the virtual camera feed.
  • 2026 elements display correctly.
  • 6DOF calibration validated.

@ecourtois ecourtois self-assigned this Dec 25, 2025
@ecourtois ecourtois added dashboard feature A new feature labels Dec 25, 2025
@ecourtois ecourtois linked an issue Dec 25, 2025 that may be closed by this pull request
@ecourtois ecourtois force-pushed the 189-add-virtual-camera-support-for-full-simulation-eurobot-2026-rules branch from df6cbdd to 5070c8d Compare December 28, 2025 15:31
Copy link
Collaborator

@mlecriva mlecriva left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

I've added some suggestions about using 4×4 homogeneous transformation matrices instead of separate 3×3 rotation matrices and translation vectors.

From my experience with similar computations in a previous robotics project, this approach:

  • Simplifies transformation chains (M_result = M1 @ M2 vs manual R/t composition)
  • Reduces the number of angle ↔ matrix conversions, which helps preserve numerical precision

I used Claude to generate the code examples, so the implementation details may need refinement but the underlying equations are based on work I've done before.

Let me know if you'd like to discuss this synchronously, I want to make sure the proposed approach covers all the use cases.

Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Python is using the equivalent en C "double" type for its "float" type.
So all C arrays bound to the Python code must use "double".

Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
The wizard type must be choice_str, not choice_integer.

Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
The path must be given by the Camera class to support variant of
Raspberry Pi cameras.

Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
…I Cam

Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
…ng mode

Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
The virtual camera in Monitor write its images in shared memory.
Implement a new camera class SimCamera that reads data from shared memory.

Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Replace the simplified 2D calibration logic (assuming fixed camera
pitch/roll) with a complete 6-Degree-Of-Freedom (6DOF) estimation.
This allows for arbitrary camera mounting orientations.

Key changes:
- Models: Add roll/pitch/yaw to `CameraExtrinsicParameters`.
- Math:
  - Implement full 3D matrix transformations for coordinate frame
    conversions (Camera <-> Robot <-> Table).
  - Add `euler_angles_to_rotation_matrix` utility.
  - Fix `R_tm` (Marker-to-Table) rotation matrix to correctly align axes
    (Z-up consistency).
- Detection:
  - Update `get_camera_position_on_table` to return full 3D orientation.
  - Update `get_camera_position_in_robot` to compute relative camera pose
    using matrix inversion ($T_{cr} = T_{rt}^{-1} \times T_{ct}$).
- Server:
  - Update `/robot_position` to derive robot pose from full 6DOF camera
    pose.
  - Update `/camera_calibration` to return extended parameters.
- Config: Switch extrinsic parameters storage from YAML to JSON.

Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Since we are now using a Raspberry Pi camera, there is no risk anymore of
contention on USB ports with cogip-detector.

Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
The discover process did not differentiate a strategy class declared in
the module with an imported one, breaking discovery of inherited strategies.

Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
If waitUpdate is used in an async task or in a thread, it will prevent
the related thread to terminated properly on program exit or reset.
So in these cases, add a timeout to sem_wait() to not block the threads
indefinitely.
The waitUpdate() function now returns a bool:
 - true if the signal was received
 - false if timed out

Use it in async tasks in Planner.

Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
This was not updated when is_intermediate attribute has been added to
the Pose class and "intermediate_pose_reached" message was sent by the
firmware.

Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
Signed-off-by: Eric Courtois <eric.courtois@gmail.com>
@ecourtois ecourtois force-pushed the 189-add-virtual-camera-support-for-full-simulation-eurobot-2026-rules branch from 1a742f7 to 7ec2dfe Compare January 2, 2026 13:08
@ecourtois ecourtois requested a review from mlecriva January 2, 2026 13:10
Copy link
Collaborator

@mlecriva mlecriva left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ecourtois ecourtois merged commit 59c2aea into master Jan 2, 2026
4 checks passed
@ecourtois ecourtois deleted the 189-add-virtual-camera-support-for-full-simulation-eurobot-2026-rules branch January 2, 2026 14:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Virtual Camera support for full simulation & Eurobot 2026 rules

2 participants