ros2_controllers icon indicating copy to clipboard operation
ros2_controllers copied to clipboard

6-wheel rover controller

Open sees1 opened this issue 1 year ago • 3 comments

I realize a six-wheel controller (6 x 4) for lunar rover on ros2_controller base now and maybe it relevant for this repo. I can modify steering controller library or write controller from scratch.

sees1 avatar Aug 07 '24 16:08 sees1

Can you outline the kinematics of such a rover? It isn't a skid steer, you think of a rocker-bogie suspension system?

christophfroehlich avatar Aug 07 '24 20:08 christophfroehlich

yeah, like rocker-bogie with front, middle and rear pair of wheel, where front and rear wheels are steerable and turn in the same direction.

sees1 avatar Aug 08 '24 18:08 sees1

Do you need other kinematic equations like described here? If yes, please start with a PR updating the docs.

Then: we could implement this by refactoring the steering_controllers_library by not implementing the resulting vehicle-kinematics in the lib, but only axis-specific kinematics and the composition is done in the respective controller implementations. This would also help here #692. But this is a bigger change as what you are asking for.

christophfroehlich avatar Aug 12 '24 09:08 christophfroehlich

This issue is being labeled as stale because it has been open 45 days with no activity. It will be automatically closed after another 45 days without follow-ups.

github-actions[bot] avatar Mar 26 '25 12:03 github-actions[bot]

Hello @christophfroehlich and everyone,

I came across this issue while working on my own project involving a six-wheel rover. If no one is actively working on this, I'd like to contribute, as I'm already working on a similar implementation.

My understanding of the plan is to:

Define and document the kinematic equations for this type of steering system.

Then, refactor the steering_controllers_library to separate vehicle-kinematics from axis-specific kinematics.

Just wanted to confirm, is this still the desired path forward? If so, I'm happy to start drafting the documentation for the kinematics.

Looking forward to your guidance.

silanus23 avatar Jul 05 '25 13:07 silanus23

Hello @christophfroehlich,

As requested in PR #1822 , here is my design proposal for the refactored steering library. This plan is designed to be a low-risk, additive approach that introduces a new, more flexible controller without affecting the existing library.

Proposal: A Refactored, Plugin-Based Steering Controller Library Motivation The current steering_controllers_library has a monolithic design that tightly couples the core controller logic with specific kinematic implementations (Bicycle, Tricycle, Ackermann). This architecture presents several challenges:

Lack of Extensibility: Adding support for new, more complex kinematic models, such as the six-wheel, four-wheel-steering rover, requires modifying the core library itself. This is not a scalable solution.

Configuration Complexity: The parameter interface is ambiguous and not easily adaptable to different vehicle types.

High Maintenance Burden: The central library becomes increasingly complex with each new model, making it difficult to maintain and debug.

This document proposes a new architecture that addresses these issues by creating a truly kinematics-agnostic steering controller.

Proposed Architecture: A New, Additive Implementation The proposal is to introduce a new, refactored controller, generic_steering_controller, to exist alongside the current library. The existing steering_controllers_library and its controllers will remain untouched, ensuring zero disruption for current users.

The new controller will be built on pluginlib, separating the generic control logic from the specific mathematical models.

Core Components

  1. The GenericSteeringController

This will be the main controller class, inheriting from controller_interface::ChainableControllerInterface. Its responsibilities will be limited to:

Interfacing with the ros2_control framework and hardware interfaces.

Managing ROS 2 parameters, subscribers, and publishers.

Loading the appropriate kinematic model plugin at runtime based on a YAML parameter.

Calling the plugin's methods within the real-time update loop.

The controller itself will have zero knowledge of any specific robot kinematics.

  1. The KinematicModelBase Interface

A new abstract base class, KinematicModelBase, will be created to define the "contract" that all kinematic plugins must adhere to. This ensures a standard interface between the generic controller and any kinematic model.

Note: To enforce a clean public API and proper separation of concerns, this base class will be defined in its own header file (e.g., kinematic_model_base.hpp).

// A simplified view of the proposed interface namespace generic_steering_controller { class KinematicModelBase { public: virtual ~KinematicModelBase() = default;

// Called once to allow the plugin to configure itself virtual void configure( const rclcpp::Node::SharedPtr & node, const std::vectorstd::string & traction_joints, const std::vectorstd::string & steering_joints) = 0;

// Called in the real-time loop to calculate commands virtual std::pair<std::vector, std::vector> get_commands(double linear_vel, double angular_vel) = 0;

// Called in the real-time loop to update odometry virtual void update_odometry(const rclcpp::Duration & period) = 0; }; }

Configuration Example The configuration will be clean and two-tiered. The main controller reads its parameters, and the loaded plugin reads its own.

generic_steering_controller: ros__parameters: # 1. Controller loads this plugin by name kinematics_plugin_name: "six_wheel_kinematics/SixWheelKinematics"

# Controller gets the joint lists
traction_joints: ["j1", "j2", "j3", "j4", "j5", "j6"]
steering_joints: ["s1", "s2", "s3", "s4"]

2. The loaded plugin reads its own specific parameters

six_wheel_kinematics: ros__parameters: d1: 0.4 d2: 0.5 d3: 0.5 d4: 0.45 wheel_radius: 0.15

silanus23 avatar Jul 21 '25 07:07 silanus23