Gap
RosBridgedRobot covers differential-drive bases: Twist on cmd_vel plus /odom. Ackermann cars expose neither. The AWS DeepRacer - the most widely owned ROS 2 car - takes normalized {angle, throttle} (deepracer_interfaces_pkg/msg/ServoCtrlMsg) on /webserver_pkg/manual_drive, publishes no odometry, and must first be switched into manual mode via a two-step service handshake (/ctrl_pkg/vehicle_state state=1, then /ctrl_pkg/enable_state is_active=true). Today a strands agent cannot drive it at all. Same shape applies to F1TENTH and most RC-scale Ackermann platforms.
Proposal
AckermannRosRobot beside RosBridgedRobot in strands_robots/mesh/, same thin design (no ROS 2 state, everything forwarded through use_ros): identical drive(linear, angular, duration) fleet contract with an internal bicycle-model conversion to servo values, a declarative init_services enable handshake run once before the first command, from_deepracer() preconfigured stock wiring, conditional get_scan, and a safety posture of clamps + loud rejections + guaranteed trailing-zero on timed commands (stop() never gated). No get_pose - the stock platform has no odometry.
PR to follow from fork.
Gap
RosBridgedRobotcovers differential-drive bases: Twist oncmd_velplus/odom. Ackermann cars expose neither. The AWS DeepRacer - the most widely owned ROS 2 car - takes normalized{angle, throttle}(deepracer_interfaces_pkg/msg/ServoCtrlMsg) on/webserver_pkg/manual_drive, publishes no odometry, and must first be switched into manual mode via a two-step service handshake (/ctrl_pkg/vehicle_statestate=1, then/ctrl_pkg/enable_stateis_active=true). Today a strands agent cannot drive it at all. Same shape applies to F1TENTH and most RC-scale Ackermann platforms.Proposal
AckermannRosRobotbesideRosBridgedRobotinstrands_robots/mesh/, same thin design (no ROS 2 state, everything forwarded throughuse_ros): identicaldrive(linear, angular, duration)fleet contract with an internal bicycle-model conversion to servo values, a declarativeinit_servicesenable handshake run once before the first command,from_deepracer()preconfigured stock wiring, conditionalget_scan, and a safety posture of clamps + loud rejections + guaranteed trailing-zero on timed commands (stop()never gated). Noget_pose- the stock platform has no odometry.PR to follow from fork.