1. Suggested architecture

Navigation or teleoperation publishes /cmd_vel. The base node converts linear and angular velocity into wheel targets and sends them over CAN or another suitable interface. Fast current and velocity loops belong on the MCU or motor drive, not a regular Linux node.

2. Convert body velocity to wheel speed

For a differential drive with wheel radius r and track width L, left-wheel angular speed is (v - ωL/2)/r and right-wheel speed is (v + ωL/2)/r. Keep units explicit and apply velocity and acceleration limits before sending commands.

3. Odometry and TF

Convert encoder counts into wheel displacement and update the robot pose. Keep map, odom, base_link and sensor frames consistent in naming and axis orientation. Wheel odometry drifts over time; consider an IMU and SLAM where accuracy requires them.

4. Watchdog and safe behavior

If a fresh command is not received within the configured timeout, ramp the target to zero and place the drive in a safe state when appropriate. Detect CAN loss, encoder faults, overcurrent, overheating and controller resets. Recovery must be deliberate and must not cause unexpected motion.

5. Test in stages

Validate nodes and messages in simulation first. Then test motor direction and encoders with wheels lifted and current limits enabled. Continue with low-speed movement, emergency stop, communication loss and restart tests. Log commands, feedback, faults and timestamps for efficient debugging.

Takeaway

A documented hardware interface, versioned CAN messages and repeatable tests make a robot easier to maintain. Stabilize control and safety before adding more complex navigation features.