Skip to content


In Walk Kicks are generated by the module WalkKickEngine. The general idea is that all kicks are configured by relative ball positions, which are converted into walk step sizes. This allows us to hit the ball accurate. But as precise kicks can not be modelled by just one walk step, all kicks can be defined by multiple relative ball positions within one walk step. The resulting walk step sizes are then executed all within one walking step by interpolating between them.

The overall simplified structure in the motion framework is shown below.

Motion Framework

Kick definition

For all new added kicks, the WalkKickEngine will apply a few assumptions, if not otherwise implemented:

  • All kicks are assumed to be defined as the left foot being the one kicking the ball
  • All kicks are expected to have at least two walk steps
    • The first walk step is the pre step, which does not touch the ball
    • All parameters must be defined for the right foot
    • The coordinate system is relative to the right foot, e.g. an offset of 0 for the y value equals the ball being in the middle of the foot
    • The second walk step is the kick step, which kicks the ball
    • All parameters must be defined for the left foot
    • The coordinate system is relative to the left foot
    • For more additional walk steps afterwards, left and right foot are alternately defined
    • For a mirror kick, e.g. kicking with the right leg, all parameters are automatically correctly mirrored

If you want to have a two step walk kick, but which is also allowed to skip the pre step, you need to add special checks at two locations in the WalkKickEngine. For the pre planning in canStart() the code must know that it is ok when the current swing phase is already the kick leg and afterwards uses the correct walk step from the configuration, e.g. skipping the first one. The createPhase() methode must also know whether the first step is skipped.

For other special kicks like side kicks or our kick for close range duels, which places the robot behind the ball with a V-shape in the feet, some more extra handling is needed.

Joint Offsets

To generate kicks with more control over their maximum strength, e.g. kicking the ball as far as possible, we use position offsets. Those ensure the kicking foot will move very fast forward and touch the ball with a high velocity, but also reduce the risk of colliding unintentionally with the ground when interpolating the 3D pose and applying just simple inverse kinematics.

An example for the offset applying is shown below. We define three time points, based on the percentage of the executed step, to interpolate from 0 to the maximum offset value and afterwards back to 0 again.

Motion Framework


An example of a subset of the parameters, which can be found in Config/Robots/Default/walkKickEngine.cfg are shown below:

walkKicksWithRestrictedStart = [forward, turnOut, forwardAlternative, forwardLong];
forward = {
  maxXDeviation = {min = -100; max = 40;};
  maxYDeviation = {min = -40; max = 40;};
  additionalXDeviation = {min = 0; max = 10;};
  additionalYDeviation = {min = -25; max = 25;};
  additionalXDeviationJustHitTheBall = {min = -20; max = 20;};
  additionalYDeviationJustHitTheBall = {min = -25; max = 90;};
  maxAngleDeviation = 6deg;
  maxClipBeforeAbortX = {min = -200; max = 80;};
  maxClipBeforeAbortY = {min = -15; max = 15;};
  maxClipBeforeAbortRot = {min = -6deg; max = 6deg;};
  maxClipBeforeAbortJustHitTheBallX = {min = -200; max = 80;};
  maxClipBeforeAbortJustHitTheBallY = {min = -50; max = 50;};
  maxClipBeforeAbortJustHitTheBallRot = {min = -8deg; max = 8deg;};
  sideDeviationScalingBasedOnLastStep = {min = -0.2; max = 0.2;};
  kickKeyFrame = [
      useSlowSupportFootHeightAfterKickInterpolation = false;
      useSlowSwingFootHeightInterpolation = 0;
      overrideOldSwingFoot = none;
      overrideOldSupportFoot = none;
      numOfBalanceSteps = 0;
      keyframes = [
          relativePositionToBallMax = {x = -150; y = -100;};
          relativePositionToBallMin = {x = -150; y = -100;};
          offsetSwingFootMax = {x = 0; y = 0;};
          offsetSwingFootMin = {x = 0; y = 0;};
          directionRatio = 1;
          reachPositionRatio = 0.5;
          speedUpSwingPositionScaling = {min = 1; max = 1;};
          useDefaultReachPositionRatio = false;
      jointOffsets = [
          joint = lHipPitch;
          offset = -15deg;
          minRatio = 0.25;
          middleRatio = 0.65;
          maxRatio = 1;
          minimumRatio = 0.25;
          shiftByKeyFrame = -1;
          joint = lAnklePitch;
          offset = 10deg;
          minRatio = 0.4;
          middleRatio = 0.65;
          maxRatio = 1.2;
          minimumRatio = 0.5;
          shiftByKeyFrame = -1;
          joint = lKneePitch;
          offset = -10deg;
          minRatio = 0.5;
          middleRatio = 0.65;
          maxRatio = 0.85;
          minimumRatio = 0.5;
          shiftByKeyFrame = -1;

Following are the parameters explained:

  • walkKicksWithRestrictedStart: List of all kicks, that have restricted starting conditions. This is done because the robots are not able to change their walking direction immediately, therefore standing still for one or two walking steps are needed to ensure that the kick is executed correctly. This is mainly due the constraint, that each walking step has a duration of 250 ms, which is not enough to execute every kick from every starting state. If in the MotionRequest the field alignPrecisely is set to justHitTheBall, then those restrictions are ignored.
  • walkKicksList: Contains all kicks, with forward used as an example.
  • max[X|Y]Deviation: Describes the max allowed deviation to the ball, compared to the planned position in kickInfo.cfg. Otherwise the robot might try to kick a ball that is still too far away and not even reachable. These deviations are additionally increased with the parameters additional[X|Y]Deviation and additional[X|Y]DeviationJustHitTheBall, based on the alignPrecisely field in the MotionRequest.
  • maxClipBeforeAbort[JustHitTheBall][X|Y|Rot]: Describes the max allowed clipping of the planned step sizes to the to be used ones. Are the difference higher than the values in those parameters, the kick is aborted (or not even started).
  • kickKeyFrame: Contains the steps of the kick.
  • useSlowSupportFootHeightAfterKickInterpolation: Let the last support foot interpolate its height slower back to zero than normal. This is important for strong kicks like forwardLong.
  • useSlowSwingFootHeightInterpolation: The WalkingEngine increases the step height duration interpolation based on the side step size. This value is used to replace the side step size to increase the step height duration. This helps to prevent for stronger kicks an early ground contact.
  • overrideOld[Swing|Support]Foot: Defines if feet positions of either foot shall be set based on the last joint request or last measured joints, not neither of both. Again this is important for strong kicks, as those result in a huge difference between what was requested and what the robot actually did.
  • numOfBalanceSteps: Sets how many walking steps after the kick the WalkingEngine shall calculate more stable step sizes.
  • keyframes: Contains the keyframes for the current step. In theory this allows for more curved walking steps.
  • relativePositionToBall[Max|Min]: Describes the relative position to the ball, which is used to determine the needed step size. Min and max are used to interpolate based on the requested kick power.
  • offsetSwingFoot[Max|Min]: Shifts the step size in a way, that it is not symmetrical distributed 50 % on the support foot and 50 % on the swing foot, but asymmetrical. The shift is used with the relativePositionToBall[Max|Min]. Once again based on the kick power the shift is interpolated.
  • directionRatio: Defines how much the requested rotation shall be converted. This allows that if more than one keyframe is used, the goal rotation is not reached within the first keyframe, but distributed over all keyframes.
  • reachPositionRatio: Is the interpolation factor for the keyframes. This one is only used if useDefaultReachPositionRatio is set true. Otherwise a dynamically calculated one is used.
  • speedUpSwingPositionScaling: Factor to interpolate the swing foot faster.
  • The jointOffsets are a list of additional offset, to force specific joints to move in a specific way. For example the joint lHipPitch shall gain an offset of -15°, interpolated with a sinus function from 25 % of the walk step (minRatio) to 100 % at a ratio of 65 % of the walk step (middleRatio). Afterwards the offset is interpolated back to 0° until the walk step ratio of 100 % (maxRatio). These interpolation values can be dynamically shifted based on the current keyframes (shiftByKeyFrame), to ensure some synchronicity between the offsets and the executed walk step. To allow this shift, shiftByKeyFrame must be set to the keyframe which shall be used as reference.

Adding new Kicks

To add new kicks, you need to add two different ones. First in the file Representation/Configuration/KickInfo.h you need to add the new kick for the left and right foot and also add them in the configuration file kickInfo.cfg. These two kicks are used from the behavior to select your new kick. The actual new kick must be added in Tools/Motion/WalkKickType.h. Last but not least you need to add the new kick in Config/Robots/Default/walkKickEngine.cfg. You can also skip the last step and simply load a scene in the simulation and use the command save module:WalkKickEngine.


All kicks are defined with the left leg being the kick leg.

Current Problems

Here we list the current problems:

  • The kicks are unreliable, because the supporting foot does not behave as expected, e.g. joint being stuck or moving slower or faster.
  • The turn kicks are currently to aggresive in duels with other robots, e.g. when the precision flag justHitTheBall is set. Here the kicks are often unstable.
  • The mode justHitTheBall causes the robot to do unstable kicks. It is only used in duels with other robots.
  • The mode justHitTheBall causes the robot to execute kicks, which are unable to hit the ball.
    • Break up conditions based on how much a walk step was clipped are already used. This concept does not work good enough and should be replaced.
  • At the start of a walk kick phase, the difference between the measured swing foot position and the starting requested one can be large, which lets the swing foot move unintentionally backwards before kicking the ball.
  • The overall advantage of the WalkKickEngine is that it can execute kicks fast and precise enough for passes. There are a lot of bad designs and oversights and the room to improve is large.
  • It is completely ignored that the feet are in a different staring pose that the steps are calculated. This results in errors in the trajectory.
  • Diagonal (e.g. simply moving the current swing foot position directly into the ball without edges in the trajectory) kicks are possible and kind of implemented already. They can be activated with the flag allowDiagonalKicks in the walkKickEngine.cfg.

Last update: November 28, 2023