Skip to content

Add opt-in CAN-FD support to can_core/can_node (untested on hardware) - #192

Draft
wilsonchenghy wants to merge 3 commits into
mainfrom
claude/open-arm-architecture-analysis-axyydf
Draft

Add opt-in CAN-FD support to can_core/can_node (untested on hardware)#192
wilsonchenghy wants to merge 3 commits into
mainfrom
claude/open-arm-architecture-analysis-axyydf

Conversation

@wilsonchenghy

@wilsonchenghy wilsonchenghy commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds real CAN-FD support to can_core/can_node, gated behind an opt-in enable_can_fd param (default false) so today's classic-CAN/SLCAN behavior is unchanged unless someone explicitly turns it on with CAN-FD-capable hardware. Closes the gap described in #189 (this repo currently has a dead data_bitrate field with no actual FD wiring behind it).

  • can_core.hpp: CanMessage gains is_fd/fd_bitrate_switch; CanConfig gains enable_fd (documented as opt-in/unvalidated) and clarifies data_bitrate's current scope.
  • can_core.cpp:
    • setupSocketCan() now opts the raw socket into CAN_RAW_FD_FRAMES before bind() when enable_fd is set.
    • sendMessage() branches to build/write a canfd_frame (up to 64 data bytes, CANFD_BRS for bitrate-switch) when message.is_fd, otherwise unchanged classic-frame path.
    • receiveMessage() reads into a can_frame/canfd_frame union sized for the larger type, and distinguishes which one arrived by the byte count read() returns.
    • setupSlcan() now explicitly refuses enable_fd=true rather than silently ignoring it — SLCAN (Lawicel ASCII protocol) can't carry FD frames.
  • can_node.cpp: declares/wires enable_can_fd and data_bitrate params through to CanConfig; hard-refuses to start (rather than silently degrading) if enable_can_fd=true is combined with bustype=slcan.
  • params.yaml / can/README.md: document the new params and the hardware prerequisite.

Explicitly NOT done here

  • No CAN-FD adapter or real arm was available to validate this against — I could not build (no ROS2/colcon environment in this session) or bench-test this change. Please build + bench-test on real hardware (ideally with a gs_usb/candleLight-firmware adapter) before relying on enable_can_fd: true near the motors — see the real-hardware-safety skill.
  • No change to the DBC or motorCMDCallback control-mode logic — this is transport-layer only, all messages still fit in ≤8 bytes today, so FD's wider payload isn't being used yet, only its potential bitrate/timing headroom.
  • No ros2_control/MoveIt2 migration — that's a separate, larger gap from matching OpenArm's stack (tracked separately, not in scope here).
  • SLCAN itself is untouched and still the default — this PR is purely additive (see "Rollout plan" below). No code here deletes or bypasses the existing SLCAN path.

Test plan

  • Compile in the actual ROS2/colcon workspace (untested here — no environment available)
  • Bench-test enable_can_fd: true + bustype: socketcan against a real CAN-FD-capable adapter, confirm candump -x shows FD frames on the bus
  • Confirm enable_can_fd: true + bustype: slcan fails fast with the new error rather than misbehaving
  • Confirm default config (enable_can_fd: false) is bit-for-bit unchanged behavior vs. before this PR
  • Re-verify CAN watchdog/timeout behavior on the new adapter before any real motor testing (per real-hardware-safety skill)

Rollout plan (staged, not part of this PR)

This PR is step 1 of 3. Steps 2 and 3 are deliberately separate PRs, not bundled here:

  1. This PR — add opt-in CAN-FD support, default off, zero behavior change on merge.
  2. Flip the default — once someone has bench-validated enable_can_fd: true against real CAN-FD hardware (new adapter required — the CANable/SLCAN setup cannot do FD), a follow-up PR changes params.yaml's defaults (bustype: socketcan, enable_can_fd: true) so CAN-FD becomes the active path.
  3. Remove SLCAN entirely — once step 2 has been running successfully, a further follow-up PR deletes setupSlcan(), the bustype=="slcan" branch, scripts/setup_can.sh, and the CANable-specific bring-up docs, leaving CAN-FD/SocketCAN as the only path. Tracked as a separate issue so it isn't forgotten, but intentionally not drafted as code yet — deleting the current working fallback before step 2 is validated would remove the safety net during the exact period it's needed.

Adds CANFD_MTU/canfd_frame send+receive path, CAN_RAW_FD_FRAMES socket
opt-in, and enable_can_fd/data_bitrate params -- gated behind
enable_can_fd (default false) so classic-CAN/SLCAN behavior is
unchanged unless explicitly turned on with a CAN-FD-capable adapter.
setupSlcan() refuses enable_can_fd=true since SLCAN can't carry FD
frames.

Not validated against real hardware -- no CAN-FD adapter or arm
available in this session. Needs bench testing before use in any
control loop. See can/README.md and issue #189.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants