feat(canopen): configurable axis object-offset in Ds402Drive for multi-axis drives - #757
Conversation
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Pull request overview
Adds a configurable per-axis object dictionary index offset to Ds402Drive so a single CANopen node can be controlled as multiple DS402 axes (e.g., second axis mirrored at +0x800).
Changes:
- Introduces
Config::object_offsetand stores it inDs402Drive. - Applies the offset to DS402 device-profile SDO accesses via a new
axis_object()helper. - Updates DS402 read/write helpers (controlword/statusword/modes/targets/profile params) to use the offset mapping.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
✅Static analysis result - no issues found! ✅ |
d4a04a1 to
3ddd224
Compare
New component espp/mcp266: a dual-channel controller for a Basicmicro MCP266 (RoboClaw family) over CANopen, layered on CanopenClient like Ds402Drive (transport-agnostic). Both axes are driven symmetrically; M2's CiA 402 objects mirror M1's at +0x800 via Ds402Drive's object offset. Position control uses standard CiA 402 profile position mode and is the supported capability; configure_position_loop() handles the two device quirks (the [0,0] MinPos/MaxPos clamp that zeroes every target, and the setter's D,P,I vs readback's P,I,D field order). The manufacturer speed/ duty command mirror is implemented but documented as inert on the tested firmware. Telemetry (battery, temperature) reads via the mirrored command objects. The reverse-engineered object mapping (0x2000 + command mirror, per-axis objects, position-PID field remap) lives in a host-buildable detail core with a standalone unit test. Includes an example (Twai + CanopenClient + Mcp266 position sequence), README, rst docs + Doxyfile/toctree entries, and CI example-build + component-upload registrations. Depends on the Ds402Drive object-offset feature (#757). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0153z8MvyCu6YT47myGDn4rK
|
Addressed the review comment:
|
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 2 comments.
3ddd224 to
dc9d9e4
Compare
New component espp/mcp266: a dual-channel controller for a Basicmicro MCP266 (RoboClaw family) over CANopen, layered on CanopenClient like Ds402Drive (transport-agnostic). Both axes are driven symmetrically; M2's CiA 402 objects mirror M1's at +0x800 via Ds402Drive's object offset. Position control uses standard CiA 402 profile position mode and is the supported capability; configure_position_loop() handles the two device quirks (the [0,0] MinPos/MaxPos clamp that zeroes every target, and the setter's D,P,I vs readback's P,I,D field order). The manufacturer speed/ duty command mirror is implemented but documented as inert on the tested firmware. Telemetry (battery, temperature) reads via the mirrored command objects. The reverse-engineered object mapping (0x2000 + command mirror, per-axis objects, position-PID field remap) lives in a host-buildable detail core with a standalone unit test. Includes an example (Twai + CanopenClient + Mcp266 position sequence), README, rst docs + Doxyfile/toctree entries, and CI example-build + component-upload registrations. Depends on the Ds402Drive object-offset feature (#757). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0153z8MvyCu6YT47myGDn4rK
|
Second round addressed:
|
New component espp/mcp266: a dual-channel controller for a Basicmicro MCP266 (RoboClaw family) over CANopen, layered on CanopenClient like Ds402Drive (transport-agnostic). Both axes are driven symmetrically; M2's CiA 402 objects mirror M1's at +0x800 via Ds402Drive's object offset. Position control uses standard CiA 402 profile position mode and is the supported capability; configure_position_loop() handles the two device quirks (the [0,0] MinPos/MaxPos clamp that zeroes every target, and the setter's D,P,I vs readback's P,I,D field order). The manufacturer speed/ duty command mirror is implemented but documented as inert on the tested firmware. Telemetry (battery, temperature) reads via the mirrored command objects. The reverse-engineered object mapping (0x2000 + command mirror, per-axis objects, position-PID field remap) lives in a host-buildable detail core with a standalone unit test. Includes an example (Twai + CanopenClient + Mcp266 position sequence), README, rst docs + Doxyfile/toctree entries, and CI example-build + component-upload registrations. Depends on the Ds402Drive object-offset feature (#757). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0153z8MvyCu6YT47myGDn4rK
|
Self-reviewed the full diff — no further issues. Every CiA 402 device-profile object accessor is wrapped with |
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.
…i-axis drives Ds402Drive addressed a single axis at the standard device-profile indices (controlword 0x6040, statusword 0x6041, ...), so it could not drive the second axis of a multi-axis controller. Basicmicro's MCP266, for example, mirrors every M1 object at +0x800 for M2 (0x6840, 0x6841, ...). Add Config::object_offset, applied via a new axis_object() helper to device-profile objects (0x6000-0x6FFF) only; communication and identity objects (< 0x6000, e.g. 0x1000/0x1008/0x1018) are shared by the whole device and are never offset. Default 0 keeps existing single-axis behavior unchanged, so two Ds402Drive instances (offset 0 and 0x800) can share one CanopenClient to drive both channels. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0153z8MvyCu6YT47myGDn4rK
dc9d9e4 to
6cf6776
Compare
New component espp/mcp266: a dual-channel controller for a Basicmicro MCP266 (RoboClaw family) over CANopen, layered on CanopenClient like Ds402Drive (transport-agnostic). Both axes are driven symmetrically; M2's CiA 402 objects mirror M1's at +0x800 via Ds402Drive's object offset. Position control uses standard CiA 402 profile position mode and is the supported capability; configure_position_loop() handles the two device quirks (the [0,0] MinPos/MaxPos clamp that zeroes every target, and the setter's D,P,I vs readback's P,I,D field order). The manufacturer speed/ duty command mirror is implemented but documented as inert on the tested firmware. Telemetry (battery, temperature) reads via the mirrored command objects. The reverse-engineered object mapping (0x2000 + command mirror, per-axis objects, position-PID field remap) lives in a host-buildable detail core with a standalone unit test. Includes an example (Twai + CanopenClient + Mcp266 position sequence), README, rst docs + Doxyfile/toctree entries, and CI example-build + component-upload registrations. Depends on the Ds402Drive object-offset feature (#757). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0153z8MvyCu6YT47myGDn4rK
|
Addressed the latest round:
|
New component espp/mcp266: a dual-channel controller for a Basicmicro MCP266 (RoboClaw family) over CANopen, layered on CanopenClient like Ds402Drive (transport-agnostic). Both axes are driven symmetrically; M2's CiA 402 objects mirror M1's at +0x800 via Ds402Drive's object offset. Position control uses standard CiA 402 profile position mode and is the supported capability; configure_position_loop() handles the two device quirks (the [0,0] MinPos/MaxPos clamp that zeroes every target, and the setter's D,P,I vs readback's P,I,D field order). The manufacturer speed/ duty command mirror is implemented but documented as inert on the tested firmware. Telemetry (battery, temperature) reads via the mirrored command objects. The reverse-engineered object mapping (0x2000 + command mirror, per-axis objects, position-PID field remap) lives in a host-buildable detail core with a standalone unit test. Includes an example (Twai + CanopenClient + Mcp266 position sequence), README, rst docs + Doxyfile/toctree entries, and CI example-build + component-upload registrations. Depends on the Ds402Drive object-offset feature (#757). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0153z8MvyCu6YT47myGDn4rK
New component espp/mcp266: a dual-channel controller for a Basicmicro MCP266 (RoboClaw family) over CANopen, layered on CanopenClient like Ds402Drive (transport-agnostic). Both axes are driven symmetrically; M2's CiA 402 objects mirror M1's at +0x800 via Ds402Drive's object offset. Position control uses standard CiA 402 profile position mode and is the supported capability; configure_position_loop() handles the two device quirks (the [0,0] MinPos/MaxPos clamp that zeroes every target, and the setter's D,P,I vs readback's P,I,D field order). The manufacturer speed/ duty command mirror is implemented but documented as inert on the tested firmware. Telemetry (battery, temperature) reads via the mirrored command objects. The reverse-engineered object mapping (0x2000 + command mirror, per-axis objects, position-PID field remap) lives in a host-buildable detail core with a standalone unit test. Includes an example (Twai + CanopenClient + Mcp266 position sequence), README, rst docs + Doxyfile/toctree entries, and CI example-build + component-upload registrations. Depends on the Ds402Drive object-offset feature (#757). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0153z8MvyCu6YT47myGDn4rK
…758) New component espp/mcp266: a dual-channel controller for a Basicmicro MCP266 (RoboClaw family) over CANopen, layered on CanopenClient like Ds402Drive (transport-agnostic). Both axes are driven symmetrically; M2's CiA 402 objects mirror M1's at +0x800 via Ds402Drive's object offset. Position control uses standard CiA 402 profile position mode and is the supported capability; configure_position_loop() handles the two device quirks (the [0,0] MinPos/MaxPos clamp that zeroes every target, and the setter's D,P,I vs readback's P,I,D field order). The manufacturer speed/ duty command mirror is implemented but documented as inert on the tested firmware. Telemetry (battery, temperature) reads via the mirrored command objects. The reverse-engineered object mapping (0x2000 + command mirror, per-axis objects, position-PID field remap) lives in a host-buildable detail core with a standalone unit test. Includes an example (Twai + CanopenClient + Mcp266 position sequence), README, rst docs + Doxyfile/toctree entries, and CI example-build + component-upload registrations. Depends on the Ds402Drive object-offset feature (#757). Claude-Session: https://claude.ai/code/session_0153z8MvyCu6YT47myGDn4rK Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Summary
Ds402Driveaddressed a single axis at the standard device-profile indices (controlword0x6040, statusword0x6041, ...), so it could not drive the second axis of a multi-axis controller.Basicmicro's MCP266, for example, mirrors every M1 object at
+0x800for M2 (0x6840,0x6841,0x687A, ...). This addsConfig::object_offset, applied via a newaxis_object()helper.Details
0x6000-0x6FFF). Communication and identity objects (< 0x6000, e.g.0x1000device type,0x1008device name,0x1018identity) are shared by the whole device and are never offset.object_offsetdefaults to0, so existing single-axis behavior is unchanged.Ds402Driveinstances (offset0and0x800) can share oneCanopenClientto drive both channels of a dual-axis node.Testing
ALL TESTS PASSED).🤖 Generated with Claude Code