• sales

    +86-0755-88291180

WAVEGO Gait Debugging Specific Method

Gait Debugging

Adjust the gait motion effect by modifying the gait-related parameters in ServoCtrl.h.


Related Parameters

In ServoCtrl.h, in addition to the parameters in the Single Leg Control section, the parameters used for overall gait debugging are as follows:

  • WALK_ACC: This is a distance in mm, used for the transition between the support pair and the swing pair
  • WALK_EXTENDED_Z: Unit in mm, controls the extension distance of the landing point in the left and right directions
  • WALK_SIDE_MAX: The maximum amplitude of the left and right swing of the end point of the leg, in mm
  • WALK_MASS_ADJUST: Used to adjust the offset of the center of gravity during movement. The coefficient has no unit, and the larger the value, the greater the center of gravity offset. Currently, it is only used in triangular gait
  • WALK_LIFT_PROP: The occupancy ratio (time) of the swing pair in the motion cycle. For example, 0.25 means that it is in the swinging pair in 25% of the time in a complete motion cycle. The smaller the value, the faster the swing. Theoretically the longer the support pair time, the more stable it is. This parameter is primarily limited by the servo motor's speed and the sizes of WALK_RANGE, WALK_LIFT, and WALK_ACC.
  • STEP_DELAY: Used to set the interpolation interval time for leg swings.
  • The other parameters are not set by the user and are not introduced here; they will be covered in the function debugging chapter.


Function Debugging

Diagonal Gait

According to the method introduced in single leg control, let each leg swing within its own motion cycle, with the left front leg as 1, the left rear leg as 2, the right front leg as 3, and the right rear leg as 4. When legs 1 and 4 swing according to the same motion cycle (referred to as Group A), and legs 2 and 3 swing according to the same motion cycle (referred to as Group B), Group A and Group B are phase-shifted by half a cycle. This ensures that at least one group is in support at any given moment.

void simpleGait(float GlobalInput, float directionAngle, int turnCmd){
  float Group_A;
  float Group_B;

  Group_A = GlobalInput;
  Group_B = GlobalInput+0.5;
  if(Group_B>1){Group_B--;}

  if(!turnCmd){
    singleGaitCtrl(1, 1, Group_A, directionAngle,  WALK_EXTENDED_X, WALK_EXTENDED_Z);
    singleGaitCtrl(4, 1, Group_A, -directionAngle, -WALK_EXTENDED_X, WALK_EXTENDED_Z);

    singleGaitCtrl(2, 1, Group_B, directionAngle, -WALK_EXTENDED_X, WALK_EXTENDED_Z);
    singleGaitCtrl(3, 1, Group_B, -directionAngle, WALK_EXTENDED_X, WALK_EXTENDED_Z);
  }
  else if(turnCmd == -1){
    singleGaitCtrl(1, 1.5, Group_A, 90,  WALK_EXTENDED_X, WALK_EXTENDED_Z);
    singleGaitCtrl(4, 1.5, Group_A, 90, -WALK_EXTENDED_X, WALK_EXTENDED_Z);

    singleGaitCtrl(2, 1.5, Group_B, -90, -WALK_EXTENDED_X, WALK_EXTENDED_Z);
    singleGaitCtrl(3, 1.5, Group_B, -90, WALK_EXTENDED_X, WALK_EXTENDED_Z);
  }
  else if(turnCmd == 1){
    singleGaitCtrl(1, 1.5, Group_A, -90,  WALK_EXTENDED_X, WALK_EXTENDED_Z);
    singleGaitCtrl(4, 1.5, Group_A, -90, -WALK_EXTENDED_X, WALK_EXTENDED_Z);

    singleGaitCtrl(2, 1.5, Group_B, 90, -WALK_EXTENDED_X, WALK_EXTENDED_Z);
    singleGaitCtrl(3, 1.5, Group_B, 90, WALK_EXTENDED_X, WALK_EXTENDED_Z);
  }
}

The code above is used to perform diagonal gait, with Group_A and Group_B phase-shifted by half a cycle

Group_A = GlobalInput;
Group_B = GlobalInput+0.5;
if(Group_B>1){Group_B--;}

GlobaIInput cycles from 0 to 1, and groups A and B obtain their own motion cycle parameters through the above algorithm, forming diagonal gait.

turnCmd is used to adjust the rotation direction. When turnCmd is 0, directionAngle can be used to adjust the translation direction (at which point the robot's head orientation remains unchanged)


Triangular Gait

The purpose of the triangular gait is to make the robot have at least three legs in the support pair at all times. This gait is more complex and requires more fine debugging to use. The diagonal gait mentioned above divides the four legs into two groups, A and B, while the triangular gait divides the four legs into four groups, with 1, 2, 3, and 4 corresponding to A, B, C, and D. The motion cycles of each two groups differ by at least 1/4 phase.

void triangularGait(float GlobalInput, float directionAngle, int turnCmd){
  float StepA;
  float StepB;
  float StepC;
  float StepD;

  float aInput = 0;
  float bInput = 0;
  float adProp;

  StepB = GlobalInput;
  StepC = GlobalInput + 0.25;
  StepD = GlobalInput + 0.5;
  StepA = GlobalInput + 0.75;

  if(StepA>1){StepA--;}
  if(StepB>1){StepB--;}
  if(StepC>1){StepC--;}
  if(StepD>1){StepD--;}

  if(GlobalInput <= 0.25){
    adProp = GlobalInput;
    aInput =  WALK_MASS_ADJUST - (adProp/0.125)*WALK_MASS_ADJUST;
    bInput = -WALK_MASS_ADJUST;
  }
  else if(GlobalInput > 0.25 && GlobalInput <= 0.5){
    adProp = GlobalInput-0.25;
    aInput = -WALK_MASS_ADJUST + (adProp/0.125)*WALK_MASS_ADJUST;
    bInput = -WALK_MASS_ADJUST + (adProp/0.125)*WALK_MASS_ADJUST;
  }
  else if(GlobalInput > 0.5 && GlobalInput <= 0.75){
    adProp = GlobalInput-0.5;
    aInput =  WALK_MASS_ADJUST - (adProp/0.125)*WALK_MASS_ADJUST;
    bInput =  WALK_MASS_ADJUST;
  }
  else if(GlobalInput > 0.75 && GlobalInput <= 1){
    adProp = GlobalInput-0.75;
    aInput = -WALK_MASS_ADJUST + (adProp/0.125)*WALK_MASS_ADJUST;
    bInput =  WALK_MASS_ADJUST - (adProp/0.125)*WALK_MASS_ADJUST;
  }

  if(!turnCmd){
    singleGaitCtrl(1, 1, StepA,  directionAngle,  WALK_EXTENDED_X - aInput, WALK_EXTENDED_Z - bInput);
    singleGaitCtrl(4, 1, StepD, -directionAngle, -WALK_EXTENDED_X - aInput, WALK_EXTENDED_Z + bInput);

    singleGaitCtrl(2, 1, StepB,  directionAngle, -WALK_EXTENDED_X - aInput, WALK_EXTENDED_Z - bInput);
    singleGaitCtrl(3, 1, StepC, -directionAngle,  WALK_EXTENDED_X - aInput, WALK_EXTENDED_Z + bInput);
  }
  else if(turnCmd == -1){
    singleGaitCtrl(1, 1.5, StepA,  90,  WALK_EXTENDED_X - aInput, WALK_EXTENDED_Z - bInput);
    singleGaitCtrl(4, 1.5, StepD,  90, -WALK_EXTENDED_X - aInput, WALK_EXTENDED_Z + bInput);

    singleGaitCtrl(2, 1.5, StepB, -90, -WALK_EXTENDED_X - aInput, WALK_EXTENDED_Z - bInput);
    singleGaitCtrl(3, 1.5, StepC, -90,  WALK_EXTENDED_X - aInput, WALK_EXTENDED_Z + bInput);
  }
  else if(turnCmd == 1){
    singleGaitCtrl(1, 1.5, StepA,  -90,  WALK_EXTENDED_X - aInput, WALK_EXTENDED_Z - bInput);
    singleGaitCtrl(4, 1.5, StepD,  -90, -WALK_EXTENDED_X - aInput, WALK_EXTENDED_Z + bInput);

    singleGaitCtrl(2, 1.5, StepB, 90, -WALK_EXTENDED_X - aInput, WALK_EXTENDED_Z - bInput);
    singleGaitCtrl(3, 1.5, StepC, 90,  WALK_EXTENDED_X - aInput, WALK_EXTENDED_Z + bInput);
  }
}


Compared to the diagonal gait, in addition to changing from two groups to four groups, three more parameters were added below:

float aInput = 0;
float bInput = 0;
float adProp;

These three parameters are not set by the user. They are used to dynamically adjust the center of gravity offset of the robot during motion. aInput and bInput are used to save the calculated offset, and adProp is used to calculate the offset aInput and bInput from the current position of the motion cycle.


StepB = GlobalInput;
StepC = GlobalInput + 0.25;
StepD = GlobalInput + 0.5;
StepA = GlobalInput + 0.75;

if(StepA>1){StepA--;}
if(StepB>1){StepB--;}
if(StepC>1){StepC--;}
if(StepD>1){StepD--;}

The above is used to adjust the phase difference for each set of motions, for example, the current swing order is 2 3 4 1 2 3 4 1......, you can change the above code to:

StepB = GlobalInput;
StepC = GlobalInput + 0.25;
StepA = GlobalInput + 0.5;
StepD = GlobalInput + 0.75;

The current swing order is 2 3 1 4 2 3 1 4 …, but try not to change the phase difference by 1/4.


if(GlobalInput <= 0.25){
    adProp = GlobalInput;
    aInput =  WALK_MASS_ADJUST - (adProp/0.125)*WALK_MASS_ADJUST;
    bInput = -WALK_MASS_ADJUST;
  }
  else if(GlobalInput > 0.25 && GlobalInput <= 0.5){
    adProp = GlobalInput-0.25;
    aInput = -WALK_MASS_ADJUST + (adProp/0.125)*WALK_MASS_ADJUST;
    bInput = -WALK_MASS_ADJUST + (adProp/0.125)*WALK_MASS_ADJUST;
  }
  else if(GlobalInput > 0.5 && GlobalInput <= 0.75){
    adProp = GlobalInput-0.5;
    aInput =  WALK_MASS_ADJUST - (adProp/0.125)*WALK_MASS_ADJUST;
    bInput =  WALK_MASS_ADJUST;
  }
  else if(GlobalInput > 0.75 && GlobalInput <= 1){
    adProp = GlobalInput-0.75;
    aInput = -WALK_MASS_ADJUST + (adProp/0.125)*WALK_MASS_ADJUST;
    bInput =  WALK_MASS_ADJUST - (adProp/0.125)*WALK_MASS_ADJUST;
  }

The code above is used to calculate aInput and bInput, the specific center of gravity offset position, with the main purpose is to move the center of gravity to the triangle formed by the horizontal projection of the three feet currently on the support pair. You can modify the code above (the calculation logic and the weight coefficient of 0.125) or delete it to observe the changes in the action.

The rest of algorithm logic for the triangular gait is the same as that for the diagonal gait. Gait adjustments need to be made by combining with the single leg control and the parameter adjustment in the relevant parameters above.

TAG: Orange Pi Zero 3 UPS HAT D Raspberry Pi 5 Official Original AI Kit Hailo8l 13Tops/26Tops PCIe M.2 HAT+ Board For Pi5 Multi Protection Raspberry Pi 5 PCM5122 I2S Audio Card DAC Also For PI4 /PI3 /Zero Series Core3566102000 ESP32‑S3 13.3-inch E6 Full-Color E-Ink e-Paper Display Raspberry Pi DSI ESP32‑S3 LoRa Development Board with LR1121 3rd Generation RF Chip USB Stamp Hole Raspberry Pi 5 PCIe to M.2 NVMe SSD Adapter Board C HAT Pi5-PCIe-2280-2242-2230 xiaozhi AI Character Personality Configuration Tutorial ESP32 S3 Development Board 2.8 inch B LCD 2.8inch Display 480x640 TouchScreen QMI8658 Sensor / Battery Port LVGL/HMI For Arduino Template: Pico-get-start Raspberry Pi 11.6 inch LCD HDMI /Type C Display In-Cell Capacitive TouchScreen 1768x828 For Jetson Nano/mini Computer PC ESP32 C6 Development Board 1.28 inch LCD Display Screen 240x240 GC9A01A SD card slot SpotPear Raspberry Pi 5 TTL RS232 to CAN Raspberry Pi 8.8 inch DSI MIPI Display LCD Capacitive TouchScreen 480x1920 ESP32-C3FN4