Skip to content

Update seires legged branch#3

Merged
HydrogenZp merged 14 commits intoHydrogenZp:series_leggedfrom
WiseL00k:series_leg
Feb 27, 2026
Merged

Update seires legged branch#3
HydrogenZp merged 14 commits intoHydrogenZp:series_leggedfrom
WiseL00k:series_leg

Conversation

@HydrogenZp
Copy link
Owner

No description provided.

@HydrogenZp HydrogenZp merged commit ab58490 into HydrogenZp:series_legged Feb 27, 2026
1 of 5 checks passed
@gemini-code-assist
Copy link

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refactors the bipedal wheel controller to enhance its robustness and configurability. It centralizes Virtual Model Control logic into a dedicated class, improves the precision and adaptability of leg state detection and recovery behaviors, and introduces new parameters for fine-tuning control. These changes aim to make the controller more resilient to various operational conditions and easier to manage.

Highlights

  • VMC Class Integration: Introduced a new VMC class to centralize Virtual Model Control calculations for leg position, speed, and torque conversion, improving modularity and maintainability.
  • Enhanced Leg State Detection and Recovery: Refactored leg state detection logic across StandUp, Recover, and Upstairs modes, introducing LegStateThresholdParams for configurable thresholds and improving recovery mechanisms with new PID control strategies.
  • Parameter Refinements and New Parameters: Added new parameters l1 and l2 for VMC, theta_bias to BiasParams, and a comprehensive LegStateThresholdParams struct. Tuned existing parameters for Kalman filter, slip detection, and PID controllers.
  • ROS Interface Updates: Updated the ROS publisher for leg status from leg_len_status_pub_ to upstair_status_pub_ and changed its message type to rm_msgs::LeggedUpstairStatus.
  • Build System Improvement: Modified CMakeLists.txt to use file(GLOB_RECURSE ...) for bipedal wheel controller source files, simplifying the build configuration.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • rm_chassis_controllers/CMakeLists.txt
    • Grouped bipedal wheel controller source files using GLOB_RECURSE for cleaner build configuration.
  • rm_chassis_controllers/include/rm_chassis_controllers/bipedal_wheel_controller/controller.h
    • Added new ROS message includes and low-pass filter includes.
    • Introduced a new LegStateThresholdParams shared pointer and a setupThresholdParams method.
    • Modified the pubLegLenStatus function signature and changed the leg_len_status_pub_ to upstair_status_pub_.
  • rm_chassis_controllers/include/rm_chassis_controllers/bipedal_wheel_controller/controller_mode/recover.h
    • Defined new enums for RecoveryChassisState, LegRecoveryCalibratedState, and LegState.
    • Modified the constructor to accept an additional PID controller for theta difference.
    • Removed setUpLegMotion and detectLegRelState methods.
  • rm_chassis_controllers/include/rm_chassis_controllers/bipedal_wheel_controller/controller_mode/stand_up.h
    • Added a detectLegState method and new member variables for desired leg angles and lengths, spring force, and a shared pointer for LegStateThresholdParams.
  • rm_chassis_controllers/include/rm_chassis_controllers/bipedal_wheel_controller/controller_mode/upstairs.h
    • Added a detectLegState method and a shared pointer for LegStateThresholdParams.
  • rm_chassis_controllers/include/rm_chassis_controllers/bipedal_wheel_controller/definitions.h
    • Extended BiasParams with a theta field.
    • Introduced a new LegStateThresholdParams struct to define various leg state thresholds.
  • rm_chassis_controllers/include/rm_chassis_controllers/bipedal_wheel_controller/helper_functions.h
    • Removed the global detectLegState function.
    • Modified the computePidLegCommand function and added new helper functions for PID control based on angle velocity, angle, and length.
  • rm_chassis_controllers/include/rm_chassis_controllers/bipedal_wheel_controller/series_legged_vmc_controller.h
    • Included the new VMC.h header.
    • Added a std::unique_ptr<VMC> member for VMC calculations.
  • rm_chassis_controllers/include/rm_chassis_controllers/bipedal_wheel_controller/vmc/VMC.h
    • Added a new header file defining the VMC class with methods for calculating leg position, speed, and joint torques from force/torque, along with a Jacobian calculation.
  • rm_chassis_controllers/include/rm_chassis_controllers/chassis_base.h
    • Modified the follow method to be virtual.
  • rm_chassis_controllers/src/bipedal_wheel_controller/controller.cpp
    • Initialized leg_threshold_params_ and included it in the setup process.
    • Updated publisher for leg status to upstair_status_pub_ with a new message type.
    • Adjusted Kalman filter A_ matrix and slip_flag_ threshold.
    • Modified clearStatus to use bias_params_->x.
    • Updated overturn detection logic.
    • Changed VMC angle calculations to use M_PI instead of M_PI_2 for hip joints.
    • Corrected leftWheelVel calculation.
    • Updated Kalman filter predict and update calls.
    • Adjusted x_left_[3] threshold.
    • Changed legged_chassis_status_msg.roll calculation.
    • Set balance_mode_ to SIT_DOWN in stopping.
    • Added theta_bias to setupBiasParams and implemented setupThresholdParams.
    • Updated pubLegLenStatus to publish rm_msgs::LeggedUpstairStatus.
  • rm_chassis_controllers/src/bipedal_wheel_controller/controller_mode/mode_manager.cpp
    • Updated the constructor for Recover mode to pass an additional PID controller.
  • rm_chassis_controllers/src/bipedal_wheel_controller/controller_mode/normal.cpp
    • Applied bias_params_->theta and bias_params_->pitch to leg state calculations.
    • Modified the conditions for transitioning to UPSTAIRS mode and the protection logic for entering RECOVER mode.
  • rm_chassis_controllers/src/bipedal_wheel_controller/controller_mode/recover.cpp
    • Modified the constructor to accept pid_theta_diff.
    • Removed previous leg state detection and motion setup.
    • Implemented detectChassisStateToRecover and updated the control logic to use new PID commands for leg length and angle velocity, incorporating T_theta_diff.
    • Adjusted the exit condition for recovery.
  • rm_chassis_controllers/src/bipedal_wheel_controller/controller_mode/sit_down.cpp
    • Removed the pitch angle condition from the exit logic for SIT_DOWN mode.
  • rm_chassis_controllers/src/bipedal_wheel_controller/controller_mode/stand_up.cpp
    • Initialized leg_state_threshold_ and updated calls to detectLegState.
    • Modified the setUpLegMotion logic to account for spring_force_ and different leg states (UNDER, FRONT, BEHIND) with adjusted desired angles and lengths.
  • rm_chassis_controllers/src/bipedal_wheel_controller/controller_mode/upstairs.cpp
    • Initialized leg_state_threshold_ and updated calls to detectLegState.
    • Adjusted desired leg angles (theta_des_l, theta_des_r) and the exit condition for UPSTAIRS mode using upstair_exit_threshold.
  • rm_chassis_controllers/src/bipedal_wheel_controller/series_legged_vmc_controller.cpp
    • Added parameter loading for l1 and l2.
    • Initialized vmcPtr_ with these parameters.
    • Updated calls to leg_pos, leg_spd, and leg_conv to use the vmcPtr_ instance.
    • Commented out gazebo-specific angle adjustments.
  • rm_chassis_controllers/src/bipedal_wheel_controller/vmc/VMC.cpp
    • Added a new source file implementing the VMC class methods, including leg_pos (calculates end-effector position), leg_spd (calculates end-effector velocity), leg_conv (converts end-effector force/torque to joint torques), and calc_jacobian (calculates the Jacobian matrix).
  • rm_chassis_controllers/test/vmc_controller.yaml
    • Updated the spring_force parameter to 0.0.
    • Increased the d parameter for pid_length to 25.
    • Added new parameters l1 and l2 for the VMC controller.
Activity
  • The pull request introduces a new VMC class and integrates it into the bipedal wheel controller, centralizing VMC calculations.
  • It refactors leg state detection and recovery logic across multiple controller modes (Recover, StandUp, Upstairs), making it more modular and configurable with new threshold parameters.
  • Parameter loading for various control aspects (model, bias, thresholds) has been updated and expanded.
  • Kalman filter and slip detection parameters have been fine-tuned.
  • ROS message publishing for leg status has been updated to a new message type.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces significant updates to the series legged bipedal controller, including refactoring VMC logic into a dedicated class and adjusting control logic across various modes. While these changes improve parameterization by removing some hardcoded values, several issues need attention. A critical bug was found where hardcoded values are used instead of configured parameters in the new VMC class. Additionally, many new magic numbers have been introduced, and large blocks of commented-out code should be removed to improve maintainability. Adhering to C++ and CMake best practices, such as using enum class and avoiding file(GLOB_RECURSE), would further enhance the code quality.

Comment on lines +48 to +49
const double l1 = 0.218;
const double l2 = 0.26;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This function uses hardcoded values for l1 and l2, but the VMC class stores l1_ and l2_ as member variables initialized from parameters. This is a critical bug, as the calculations will be incorrect if the configured parameters are different from these hardcoded values. You should use the member variables l1_ and l2_ instead.

Suggested change
const double l1 = 0.218;
const double l2 = 0.26;
const double l1 = l1_;
const double l2 = l2_;

Comment on lines +384 to +385
ROS_ERROR("Load threshold param fail, check the resist of "
"under_threshold, front_threshold, behind_threshold");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There's a typo in the error message. "resist of" should probably be "existence of" or "presence of". Clear error messages are important for debugging.

Suggested change
ROS_ERROR("Load threshold param fail, check the resist of "
"under_threshold, front_threshold, behind_threshold");
ROS_ERROR("Load threshold param fail, check the existence of "
"under_threshold, front_threshold, behind_threshold");

Comment on lines +233 to +235
if (jump_phase_ == JumpPhase::IDLE && linear_acc_base_.z < -7.0 && controller->getCompleteStand() &&
abs(vel_cmd_.x) > 0.1 && abs(x_left(3)) > 0.1 && ((left_pos_[0] + right_pos_[0]) / 2.0f) > 0.30 &&
leg_length_des > 0.30)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The values -7.0, 0.1, and 0.30 are magic numbers. They should be defined as named constants with descriptive names to improve readability and make them easier to tune.

double leg_recovery_velocity_{ 2.0 }, threshold_{ 0.05 }, leg_theta_diff_{ 0.0 }, desired_leg_length_{ 0.36 };
const double leg_recovery_velocity_const_{ 2.0 };
RecoveryChassisState recovery_chassis_state_{ ForwardSlip };
bool detectd_flag{ false };

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There is a typo in the variable name detectd_flag. It should be detected_flag for clarity and correctness.

Suggested change
bool detectd_flag{ false };
bool detected_flag{ false };

else
{
cmd.torque = angle_vel_pid.computeCommand(-4 - leg_spd[1], period);
cmd.torque = angle_vel_pid.computeCommand(-5 - leg_spd[1], period);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The magic number -5 should be replaced with a named constant to improve readability and maintainability. This makes it easier to understand the purpose of the value and to change it in one place if needed.

Comment on lines +63 to +79
theta_des = M_PI / 2 - 0.35;
length_des = 0.36;
if (leg_length > 0.35)
{
leg_state = LegState::FRONT;
}
}
else
{
theta_des = 0.0;
length_des = 0.18;
}
break;
case LegState::FRONT:
theta_des = M_PI / 2 - 0.35;
theta_des = M_PI_2 - 0.35;
length_des = 0.36;
if (abs(x[0] - theta_des) < 0.3 && abs(x[4]) < 0.3)
if ((abs(x[0] - theta_des) < 0.3 && abs(x[4]) < 0.3) || (abs(x[1]) < 0.1 && x[0] > M_PI_2))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This function contains several magic numbers (0.35, 0.36, 0.18, 0.3, 0.1). These should be replaced with named constants to improve readability and make the logic easier to understand and maintain. Consider making them configurable parameters if they need to be tuned.

}

double theta_des_l{ M_PI_2 - 0.3 }, theta_des_r{ M_PI_2 - 0.3 }, length_des_l{ 0.18 }, length_des_r{ 0.18 };
double theta_des_l{ M_PI_2 - 0.6 }, theta_des_r{ M_PI_2 - 0.6 }, length_des_l{ 0.18 }, length_des_r{ 0.18 };

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This line initializes theta_des_l and theta_des_r with magic numbers, but they are immediately overwritten on the next line by a value from parameters. This initialization is redundant and can be misleading. It should be removed.

Suggested change
double theta_des_l{ M_PI_2 - 0.6 }, theta_des_r{ M_PI_2 - 0.6 }, length_des_l{ 0.18 }, length_des_r{ 0.18 };
double theta_des_l{}, theta_des_r{}, length_des_l{ 0.18 }, length_des_r{ 0.18 };

Comment on lines +77 to +82
thigh_angle = jointThigh_.getPosition() + M_PI_2;
knee_angle = jointKnee_.getPosition() - M_PI_2;

// five link vmc
thigh_angle = jointThigh_.getPosition() + M_PI;
knee_angle = jointKnee_.getPosition();
leg_pos(thigh_angle, knee_angle, position);
leg_spd(jointThigh_.getVelocity(), jointKnee_.getVelocity(), thigh_angle, knee_angle, speed);
// thigh_angle = jointThigh_.getPosition() + M_PI;
// knee_angle = jointKnee_.getPosition();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Toggling between simulation (gazebo) and real hardware (five link vmc) code using comments is error-prone and not ideal for maintainability. Consider using preprocessor directives (#ifdef/#endif) to conditionally compile the correct block of code based on a CMake flag. This makes the configuration explicit and reduces the risk of committing the wrong code.

//

#include "bipedal_wheel_controller/vmc/VMC.h"
#include <math.h>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

In C++, it is best practice to include C standard library headers using the c prefix and no .h extension (e.g., <cmath>). This places the symbols in the std namespace.

Suggested change
#include <math.h>
#include <cmath>

bool init(hardware_interface::RobotHW* robot_hw, ros::NodeHandle& root_nh, ros::NodeHandle& controller_nh) override;
void moveJoint(const ros::Time& time, const ros::Duration& period) override;
void stopping(const ros::Time& time) override;
// void follow(const ros::Time& time, const ros::Duration& period) override;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This commented-out function declaration should be removed to keep the code clean. If the function is no longer needed, it's best to delete it entirely rather than leaving it as dead code.

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