Behaviour and how it works in the NUbots codebase.
Ysobel Sims GitHub avatar
Updated 18 Oct 2023

The behaviour subsystem includes the purpose, strategy and planning layers of the system. These utilise the Director system and will be made up of Providers and Tasks. The behaviour subsystem is responsible for the high-level decision making of the robot.


The planning layer is given a straightforward goal and uses mathematics to determine how to achieve that goal using skills. These skills are generally motions, such as kicking, walking and getting up. Examples of planners are the walk path planner and the kick planner.

Walk Path Planner

There are three main walk path planners. Each are Providers and emit Walk Tasks.

  • WalkTo: This planner is given a vector position and heading to walk to in robot space. It moves towards the position linearly and rotates to reach the given heading. As it approaches the position to walk to, it decelerates so it stops smoothly.
  • TurnOnSpot: This planner is given a direction to rotate (clockwise or anti-clockwise) and rotates in that direction on the spot.
  • TurnAroundBall: This planner assumes the ball is in front of the robot and pivots around it so that the ball is still in front of the robot. It is given a direction to rotate (clockwise or anti-clockwise). This is useful for aligning the robot with the ball and a target, ie the ball or a teammate.

Kick Planner

The kick planner checks if the ball is close enough to kick and if we are aligned towards our target, ie goal or teammate. When these conditions are satisifed, it emits a Kick Task.

Look Planner

Looking does not often need planning functionality behind it, as a vector to look to can be given directly to the skill. We do implement a LookAround planner that oscillates between points given from the module's configuration file. This is useful for looking around the field for the ball.


The strategy modules contain a high-level request that utilises environment information and the planning layer to achieve its goal. The module/strategy folder contains these strategies. We list some of these with their functions below.

  • StandStill: uses the walk engine to stand still.
  • FindBall: if the ball is not visible, uses the look and walk planners to find it
  • WalkToBall: uses ball localisation to emit a Task to the walk path planner.
  • LookAtBall: uses ball localisation to emit a Task to the look planner to look at the ball.
  • KickToGoal: uses field localisation to determine when to emit a Task to the kick planner.
  • AlignToGoal: uses field localisation to determine when to emit a Task to the walk path planner to pivot around the ball to face the goal.


The purpose layer determines the overall goal of the robot. For soccer-playing, it contains the logic for soccer positions. These modules form the root of the Director tree.


The Soccer purpose uses GameController information to determine how to act. If it is penalised, then it stands still. If it is not penalised, it determines whether to play as a striker, defender or goalie.

  • Striker: An offensive position that attempts to score goals by moving towards the ball and kicking to the goal.
  • Defender: A defensive position that attempts to prevent the opponent from scoring goals by moving towards the ball and kicking it away from the goal if the ball is in our half.
  • Goalie: A defensive position that attempts to prevent the opponent from scoring goals by staying in the goal area and diving towards the ball if the opponent tries to score.

Keyboard Walk

The keyboardwalk module is a purpose-level module used for testing and demonstration purposes. Keyboard walk can use any of the walk engines in the codebase, and acts as an interface for any one of them.

Keyboard walk uses keyboard inputs to control the robot. The inputs available are detailed in the following table.

eToggles the walk on and off. Initially it is off.
wAdds 0.01 to the walk command x-value. This value is in meters/second.
sAdds -0.01 to the walk command x-value. This value is in meters/second.
aAdds 0.01 to the walk command y-value. This value is in meters/second.
dAdds -0.01 to the walk command y-value. This value is in meters/second.
zAdds 0.1 to the walk command rotational value. This value is in radians/second.
xAdds -0.1 to the walk command rotational value. This value is in radians/second.
,Runs the kick with the left foot.
.Runs the kick with the right foot.
gRuns the get up.
Head turns to the left.
Head turns to the right.
Head turns upwards.
Head turns downwards.
rResets keyboardwalk. Head rotation is set to 0. Walk command is set to 0.
qQuits keyboardwalk.

To use KeyboardWalk, build the keyboardwalk role and run the binary.

The fake/keyboardwalk role uses HardwareSimulator, and is useful for when you don't want to run keyboard walk on the robot.

PS3 Walk

The PS3 walk module is an interface for testing and demonstrating the walk and other functionalities using a PS3 controller.

The module connects to the PS3 controller using bluetooth (or USB) and reacts based on joystick or button input.

Left Joystick HorizontalAdds rotational speed to the walk command.
Left Joystick VerticalAdds x speed to the walk command.
Right Joystick HorizontalChanges the head yaw.
Right Joystick VerticalChanges the head pitch.
TRIANGLEToggles walking on/off.
SQUAREToggles locking of the head.
R2Right kick.

To use this module, build the PS3Walk role and run the binary. Plug the PS3 controller into the robot using a USB cable. When the controller is connected to the robot, it will be paired, and you can remove the cable.

Script Runner

ScriptRunner is a purpose-level module. It takes the name of one or more script files as arguments and attempts to run the scripts. It does not take file paths, only the file name/s of the script/s to execute.

When ScriptRunner is executed, it stores the script file names passed to it as a vector of strings. When the green button on the robot is pushed, the scripts are executed in order of appearance, one after the other. ScriptRunner also provides an option to set a delay before the execution of the first script, as well as a delay between the execution of each script.

An example of using ScriptRunner to run a script called Stand.yaml is:

./scriptrunner Stand.yaml

Script Tuner

ScriptTuner is a purpose-level module. Using a command-line argument, it can either create a new script or open an existing script for editing. It uses curses to create a user interface in the terminal. Through this user interface, YAML files are created or edited that specify a script that can then be used by other modules.

A script consists of frames (also called targets) which specify the position of one or more servos at a given time. The ScriptTuner interface allows for stepping through and modifying those frames. When a frame is selected in ScriptTuner, a ServoCommand for that frame will be emitted to the robot. By stepping through multiple frames, the entire script can be played back on the robot, allowing the user to preview changes to the script.

ScriptTuner also allows for "locking" and "unlocking" servos on the robot. When a servo is "locked", its position can only be changed in ScriptTuner. When it is "unlocked", the servo can be moved physically on the robot, which will update the position value in the script. Locking a servo involves emitting a ServoCommand for the current position of the servo. Unlocking the servo involves emitting a ServoCommand with zero torque and gain.

To learn how to use ScriptTuner, read the ScriptTuner guide.

NUbots acknowledges the traditional custodians of the lands within our footprint areas: Awabakal, Darkinjung, Biripai, Worimi, Wonnarua, and Eora Nations. We acknowledge that our laboratory is situated on unceded Pambalong land. We pay respect to the wisdom of our Elders past and present.
Copyright © 2023 NUbots - CC-BY-4.0
Deploys by Netlify