Skip to content

dotbot/dotbot_simulator: add logic to load custom C based control loop function#222

Open
aabadie wants to merge 16 commits intoDotBots:mainfrom
aabadie:control_loop_ffi
Open

dotbot/dotbot_simulator: add logic to load custom C based control loop function#222
aabadie wants to merge 16 commits intoDotBots:mainfrom
aabadie:control_loop_ffi

Conversation

@aabadie
Copy link
Copy Markdown
Contributor

@aabadie aabadie commented Mar 13, 2026

In simulator_init_state.toml, just add to each robot configuration the option custom_control_loop_library to specify the custom control loop library to use. Example:

[[dotbots]]
address = "BADCAFE111111111" # DotBot unique address
calibrated = 0xff # optional, defaults to only first lighthouse calibrated
pos_x = 400 # [0, 2_000] in mm
pos_y = 400 # [0, 2_000]
theta = 0.0 # [0.0, 2pi]
custom_control_loop_library = "librobotcontrol.so"  # <= line to add

The control loop is set per robot so each robot in the swarm can use its own control loop library. The default is to use the Python based version already available in the code base.

@aabadie aabadie added the enhancement New feature or request label Mar 13, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 13, 2026

Codecov Report

❌ Patch coverage is 36.36364% with 56 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.79%. Comparing base (a22c58e) to head (b0ee900).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
dotbot/dotbot_simulator.py 36.36% 56 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #222      +/-   ##
==========================================
- Coverage   69.25%   68.79%   -0.47%     
==========================================
  Files          40       40              
  Lines        3789     3829      +40     
==========================================
+ Hits         2624     2634      +10     
- Misses       1165     1195      +30     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@geonnave
Copy link
Copy Markdown
Contributor

Very interesting!

Just confirming I understood: with this we can copy/paste the update_control library to/from the dotbot firmware code and compile it with target=host, then use it from the simulator, is that it?

If so, would it make sense to also provide an example C file (and Makefile) in the examples folder?

@aabadie
Copy link
Copy Markdown
Contributor Author

aabadie commented Mar 18, 2026

with this we can copy/paste the update_control library to/from the dotbot firmware code and compile it with target=host, then use it from the simulator, is that it?

The idea is to compile the source that is located in dotbot-firmware (or libs). There's no code to copy. The output library (.so or dylib) can be anywhere. The path to the .so/dylib is set in the simulator configuration file. I indeed plan to provide a helper Makefile or CMake project to compile the library and I'll probably move the .h/.c code in a segger library under DotBot-libs so it can be reused in dotbot-swarmit as well.

@aabadie
Copy link
Copy Markdown
Contributor Author

aabadie commented Mar 20, 2026

@geonnave I added a513149 which contains a CMake project to build the library locally. The readme explains how to use it.

self.pwm_left = self.custom_robot_control.pwm_left
self.pwm_right = self.custom_robot_control.pwm_right

if self.custom_robot_control.waypoint_idx >= len(self.waypoints):
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Shouldn't this check be before the

        self.custom_robot_control.waypoint_x = int(
            self.waypoints[self.custom_robot_control.waypoint_idx].pos_x
        )
        self.custom_robot_control.waypoint_y = int(
            self.waypoints[self.custom_robot_control.waypoint_idx].pos_y
        )

a couple lines earlier? It will break a couple lines back if self.custom_robot_control.waypoint_idx >= len(self.waypoints)

output_lines.append(f"direction = {direction}")
if control_loop_library_path is not None:
output_lines.append(
f'control_loop_library_path = "{control_loop_library_path}"'
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is generating a .TOML right? but latter the toml read looks for this field:

custom_control_loop_library: Path = None. it doesn't match

# Call the custom control loop function from the shared library
self.custom_control_loop_library.update_control(
ctypes.byref(self.custom_robot_control)
)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I didn't knew what this does, so I asked chatGPT and he said this:

Without argtypes/restype, ctypes assumes restype=c_int and performs no argument validation. On x86-64 Linux this often "works" by accident, but on other platforms (macOS ARM, Windows) or
with different calling conventions, wrong assumptions corrupt the stack. The C function update_control almost certainly returns void.
Fix: After loading the CDLL, declare the signature:
self.custom_control_loop_library.update_control.argtypes = [ctypes.POINTER(RobotControl)]
self.custom_control_loop_library.update_control.restype = None

("waypoint_threshold", ctypes.c_uint32),
("pwm_left", ctypes.c_int8),
("pwm_right", ctypes.c_int8),
]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I dont know how it is in python, but in rust we have to use #[repr(C)] . Do we have to align with the C code?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants