Professional Documents
Culture Documents
by wolf2018
The Poor Man's bi-ped Robot - using RP2040 and Micropython project consists of three instructables:
Poor man's bi-pedRobot Hardware describes how to build the robot hardware and documents the
electronics to run the servos which move the robot.
Poor man's bi-ped Robot Controller(this instructable) describes the software which is running on the
robot electronics to make the robot walk.
Poor man's Robot Remote Control describes the User interface to program the robot to walk a certain
distance and control the parameters, which in uence the way the robot walks. (to be published soon)
This Poor man's bi-ped Robot Controller instructable describes how to control a bi-ped robot, explains basic concepts
such as how to control servos using RP2040 PIO programs, a bit of inverse kinematics, walking pattern generation and
the software modules needed to make Robi the robot walk.
To implement the robot controller at least some basic Python programming experience is needed. The matter is a bit
complex and in case the hardware and/or software is not working as expected, some understanding of the code is
needed to understand and resolve the issue.
Robi is built with a WLan capable RP2040 based board to enable a "Robot Remote Control". On Robi's side a small Web
server provides a simple API to control the robot via WLan. With this API you can remotely program Robi to walk a certain
distance and set parameters, which in uence the way the robot takes steps. The UI sends status information received
from Robi.
The instructable documents the project to make it easy to reproduce, but will not go deeply into all the knowledge areas,
which are involved in controlling a bi-ped robot. Basic knowledge will be provided and I will provide links to resources,
which I found very helpful.
The software provided is a starting point and by no means is a complete robot controller, it is shared with the hope to be
a helpful resource for your robot projects.
Remarks:
all modules with the headline starting with "Basics: " in the Steps below are generic, and the software is
implemented independent of the hardware implementation for Robi, so they can be re-used or adapted
easily for other projects. The software modules are attached to the individual Steps.
This instructable will provide a test software to test-walk Robi. To use the test software a long (e.g.
>=1.5m) USB cable is needed.
Have fun reading on - and if you have questions or improvement ideas - feel free to add a comment below.
Supplies:
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 1
The hardware needed is a RP2040 based micro-controller board with WLan. I am using the RP2040 PicoW board. Add
Micropython version 1.19.1 or higher.
If you have built the robot hardware of the "Poor Man's Bi-ped Robot Hardware - Using RP2040 and Micropython"
instructable, the instructions and software below will work out of the box.
If you want to build your own bi-ped robot, continue reading. Likely many of the concepts (e.g. the inverse kinematics)
and modules (e.g. the PIO programs on the RP2040) can be used as is. Feel free to adapt the modules to your needs.
If you ended up here being curious on how to control a bi-ped robot, read on!
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 2
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 3
Step 1: Basics: PWM Servo Control Using RP2040 PIO
Servo Control:
The concept of PWM servo control is explained in attached picture. The cycle time of a standard RC type servo is 20ms.
The position of the servo arm (0 degree to 90 degree) is determined by the high time pulse width pw. Typically 0 degree
corresponds to a pw of 1ms and 90 degree corresponds to a pw of 2ms. If you use servos with di erent speci cations, see
explanation in attached picture to re-calculate for your servos' speci cations.
PWM Generation:
The RP2040 micro-controller has a very nice feature: the PIO.
With reference to the PIO PWM example in the RP2040 datasheet (section 3.6.8 PWM) the attached micropython module
was developed. For Robi the PIOPWM class is used to instantiate six state machines to control Robi's six servos.
The Robi hardware uses simple FET level shifters to boost the 0V to 3.3V output of the rp2040 to the 0V to 5V input for
the servos. These level shifters invert the signal, thus the PWM signal is generated inverted (see pictures).
Attached the PIO PWM micropython module for the RP2040 micro-controller with FET level shifters.
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 4
Download
https://www.instructables.com/F2Z/XWS8/LBXO0WFG/F2ZXWS8LBXO0WFG.py
I use inverse kinematics (IK) to calculate angles for hip, knee and ankle. For veri cation Geogebra classic is used. If you are
interesting in more details or want to use IK for your own robot, I recommend following reading:
Oscar Liang: Inverse kinematics basics tutorial . This article goes beyond what I have implemented and beyond the
capabilities of the chosen robot hardware, but the basics described in that article are helpful for any bi-ped robot project.
Geogebra classic can be found on the Geogebra Website.
For inverse Kinematics the robot hardware properties need to be known. These are upper leg length (thigh), lower leg
length (shank) and height of the hip over ground. These properties are de ned in the module robi_def.py as leg1, leg2
and height, described in more detail in Step 3.
Inverse Kinematics calculation for Robi can be found in the picture attached. Calculations are done in module
calc_angle.py
I did set following conditions for the calculation to limit the degrees of freedom:
the foot of the moving leg is always parallel to the ground
the center of mass (CoM) is moving with the moving leg
the moving leg is lifted straight up before moving forward to avoid collision with obstacles on the ground
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 5
To show how Robi walks in principle, three example pictures are attached for a 4cm step, starting with the left leg
moving. I simulated with Geogebra classic.
1. 4cm_half_step: the right leg is supporting (on the ground), the left leg is lifted by step height (1.26cm)
and half way forward (2cm). Robi's Center of Mass (point CG) has as well moved 2cm forward.
2. 4cm_step: the right leg is still on the ground and the left leg has reached the full step and is on the
ground as well. Next the right leg moves in a similar way, while the left leg is in support.
3. 4cm_end: both legs have reached the 4cm step target and are in support on the ground. This is the
starting position for the next step.
For each of these example positions of each leg - actually for much more positions in-between - the function
target_angle() in module calc_angle.py is called to calculate the angles for hip, knee, ankle and hip_1. The auxiliary angle
hip_1 is needed, because we move the CoM together with the moving leg (refer to angles a1 and h1 in rst picture).
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 6
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 7
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 8
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 9
Download
https://www.instructables.com/FS6/1KGV/LBZ3H4OX/FS61KGVLBZ3H4OX.py
We need to describe our robot's properties. These are speci c to the robot hardware and are kept in one place. All
modules access them and use the same properties. As another bene t, if you change your robot hardware, e.g. servos or
leg length, the change is maintained in one place. For Robi this place is in the module robi_def.py. This module contains
comments to explain the properties in more detail.
The module contains:
constants to instantiate the PIO PWM state machines. These constants are dependent on the servo
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 10
speci cations. For Robi the values are for standard servos with 20ms cycle time and 1ms to 2ms pulse
width.
constants for the mechanics: leg1 and leg2 length, the maximum CoM height (standing straight on both
legs), the minimum CoM height (limited by the mechanics) and a safety height for initial lifting of the
moving leg
default values for walking parameters
Servo control de nitions and limitations for each servo:
Servo identi er (name)
state machine and GPIO pin to use for the servo
o set to adjust for mechanical deviation from servo neutral position
"max_angle" mechanical limitation towards the 90 degree point of servo to avoid e.g. mechanical
blocking
"min_angle" mechanical limitation towards the 0 degree point
rotation direction
the "neutral position" of each servo for the robot standing upright
Remark: if you change these parameters, check where they are used and ensure the calculations and program controls
are still working ne. As an example: a change of the leg lengths impact the CoM min and max height and typically the
servo min and max angles.
Download
https://www.instructables.com/FC3/0DR6/LBXO11GA/FC30DR6LBXO11GA.py
Please refer to attached pictures "Robi Control Diagram" and "Robi Control Structure". You can nd the second page of
the control structure in the next step.
I opted for a modular approach so main functions are in separate modules. This reduces e ort in testing and enables re-
use. Although this Step is generic, I added function and module names of the implementation for Robi, for your
convenience. References to functions and modules are in italics.
Initialization and start up:
Numbers in bullet points below are in the sequence of startup.
1. Robot control is started by importing robi.py, the main program, which imports other modules as
needed. Remark: two modules are provided: robi_web.py to start a small Web server to control Robi over
WLan, this should be the default, and robi_test.py to control Robi using an USB cable instead. robi_test.py
is used for initial test of the hardware.
2. Initialization of the state machines for the servos by calling init_sm() in module cfg.py. PWM stays turned
o at this time, to avoid accidental servo movement
3. Connection to WLan by calling connect() in module wi Connect.py.
4. Remark: WLan credentials (SSID and passphrase) are set in module wi Connect.py
5. If connection cannot be established right away, 10 re-tries are made. If still no connection the program
exits.
6. Starting of the Web server in robi_comm.py to expose the API at port 8081 at the IP address obtained by
connecting to the WLan. The Web server runs until a "stop" action is requested, which shuts down the
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 11
robot. A reset or power o /on cycle is needed to restart the robot.
7. in the main program robi_web.py (or robi_test.py) exceptions are managed
Remarks:
It is recommended to connect the USB interface of the RP2040 pico when you start the rst time or need
to debug. All modules print out status and debug information to the USB interface.
I implemented three debug levels. The level is de ned in module cfg.py by setting the value of variable
debug to: 0=no info, 1=high level info, 2=detailed info.
Additionally many modules have print statements commented out. Remove the comment "#" infront of
the print statements to get more detailed information
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 12
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 13
Step 5: Basics: Walking Pattern Generation
The attached chart shows the modules and their functions for walking pattern generation and execution.
De nitions and constraints:
There are many degrees of freedom if we create a walking pattern, so we need to take some de nitions to limit them. The
robot hardware we built has some mechanical constraints and nally there is physics we cannot ignore, e.g. if we move
the Center of Mass (CoM) outside the support area, which is basically our robots foot, the robot will tilt and fall.
The Center of Mass (CoM):
the maximum CoM o the ground is the length of the legs while Robi stands straight. For Robi this is
10.7cm.
the minimum CoM is 9cm by experiment. If we move the CoM lower servos will start to block
mechanically while walking. If servo calibration is done properly no damage will happen.
the CoM moves together with the moving leg. This limits the step size, but is easier to calculate and
control.
the CoM needs to be inside the support area of at least one foot. From ankle to the tip of the foot we
measure 4cm, thus the maximum step we can take is 4 cm. We could try to take larger steps, but Robi will
start to fall forward if the CoM goes beyond the tip of the supporting foot. This can be controlled by ne
tuning the walking parameters, but I opted for now to limit the step size. See picture to illustrate that
constraint.
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 14
Walking pattern:
the resting position is Robi standing straight, the CoM is at its maximum height.
Walking starts with lowering the CoM to the ready position, still both legs on the ground. Typical values
for Robi are between 9.5 and 10.5 cm.
The CoM will always stay at the height of the ready position while walking (see Step 2 Inverse Kinematics)
We start with a simple walking pattern, starting with the left leg:
1. Left leg is lifted straight up to a safety height above the ground to avoid obstacles
2. Left leg is moved forward a de ned step width
3. The CoM is moved the same distance forward as the left leg
4. Left leg is moved straight down to the ground
5. Right leg is lifted straight up to safety height
6. Right leg is moved forward the de ned step width
7. Right leg moves straight down to the ground
The walking pattern can be more complex, of course. It is a matter of implementing the algorithm and
adjust the inverse kinematics, if required.
Optimization:
1. Experiments show: if the walking pattern is executed at full servo speed, Robi will not walk nicely,
because the servos are programmed in sequence. As a result the rst servo will execute the full
movement right away, the second servo will respond with a delay and the third servo will lag behind. At a
smooth surface the standing foot may even slip backwards instead of the moving leg moving forward. To
achieve a smoother walk:
2. Lifting the leg can still be done in one move
3. moving the leg and the CoM forward will be split into many smaller steps, let's call them micro steps. The
servos will still be programmed in a sequence, but with many much smaller movements.
4. Robi is walking with one speed only, which is pretty fast. To allow for speed adjustments and slower
movement
5. a delay is introduced. Once a micro step is executed the controller waits the delay value of time before
the next micro step is executed. Be aware if the dealy is too large, Robi might tilt and fall
6. the step size can be reduced, so many more steps are needed to make the target distance.
7. You might see Robi walking in a circle instead of a straight line. One of the most probable causes is the
servo neutral positions are not aligned properly. See Step 7 and (re-)do the servo alignment. Remark: I am
using cheap servos with plastics gears. They are not totally accurate in reaching their position, so it could
be that over time they go out of alignment. Then I re-do the calibration and update the values in the
module robi_def.py.
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 15
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 16
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 17
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 18
Step 6: Development Environment
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 19
When you connect to the rp2040 picoW board after downloading and start micropython you get a message similar to
below with the three chevrons >>> being the micropython REPL prompt:
MicroPython v1.19.1 on 2022-09-14; Raspberry Pi Pico W with RP2040
Type "help()" for more information.
>>>
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 20
Step 7: Initial Calibration of the Servos
If you have built Poor man's bi-pedRobot Hardware , you probably have your servos aligned and can skip to the next
step. If you still need to do (or re-do) the alignment here is the procedure:
Copy pio_pwm.py from Step 1 to the RP2040 pico board.
Copy servo_alignment.py from this Step to the RP2040 pico board.
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 21
At the micropython >>> prompt type: import servo_alignment , which will start the program and a welcome screen will
be displayed (see picture).
Servo alignment:
Write down the angle for the neutral position and the end points for each servo. This data is needed later for the Robot
controller. E.g. when Robi is initialized all servos move to their neutral position and Robi stands straight.
The picture shows the nal result after the neutral position alignment of all servos. It shows as well a small mis alignment
of the hip servo.
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 22
1. Start the servo alignment program (if not already running) and enter the angle for the neutral position.
2. If the neutral position is 45 degrees:
3. move the servo towards the zero degree position in small steps, e.g. 45, 40, 35 ...
4. when the servo does not move anymore, this could be at 0 degree or a larger number, you are at the
minimum end point. If the servo starts humming loud it blocks, then move back a bit by increasing the
angle. Make note of the minimum angle.
5. move the servo to the neutral position (45 degree) and then move it towards the 90 degree position in
small steps, e.g. 45, 50, 55...
6. when the servo does not move anymore, this could be at 90 degree or a smaller number you are at the
maximum end point. If the servo starts humming loud it blocks, then move back a bit by decreasing the
angle. Make note of the maximum angle .
7. Remark: the ankle servos will likely only move between 10 and 75 degree.
8. If the neutral position is 0 degrees:
9. move the servo towards the 90 degree position in small steps, e.g. 0, 5, 10, 15...
10. when the servo does not move anymore, this could be at 90 degree or a smaller number you are at the
maximum end point. If the servo starts humming loud it blocks, then move back a bit by decreasing the
angle. Make note of the maximum angle .
Remark: If you play with the servo alignment program, the pico state machines might not always properly de-initialize. If
that happens they keep their memory allocated and you may run out of memory at a certain point. If you get an "OSError:
[Errno 12] ENOMEM" do a soft reset (Ctrl-D). If a soft reset does not x the problem, switch power for the pico o and on
for a clean micropython restart.
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 23
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 24
Download
https://www.instructables.com/FF0/XVFL/LDN40CXJ/FF0XVFLLDN40CXJ.py
This step describes how to install all software including dependencies to make Robi walk. Follow the instructions below
step by step, as the sequence is important for your success.
Connect to the RP2040 pico board using your favorite IDE or use mpremote (see Step 6).
Copy Robi con guration le:
Copy cfg.py (attached to this step) to the RP2040 pico board.
Download
https://www.instructables.com/FHR/TQV6/LDPYUDTS/FHRTQV6LDPYUDTS.py
Download
https://www.instructables.com/FQE/ZB52/LDPYUA17/FQEZB52LDPYUA17.py
Download
https://www.instructables.com/FW4/CN5S/LDPYUA18/FW4CN5SLDPYUA18.py
Download
https://www.instructables.com/FFS/V8JM/LDPYUA19/FFSV8JMLDPYUA19.py
Download
https://www.instructables.com/FEH/E21D/LDPYUA1A/FEHE21DLDPYUA1A.py
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 27
Download
https://www.instructables.com/FC2/ZKVA/LDPYUA1B/FC2ZKVALDPYUA1B.py
To test the controller and make Robi do its rst steps, connect to the RP2040 pico board using your favorite IDE or use
mpremote (see Step 6). Connect Robi to your computer using a long USB cable.
At the REPL >>> prompt enter:
>>> import robi_test
The test program should start automatically. It will load all needed modules. A simple user interface is launched (see
picture). Should there be anything missing an error message will be reported.
One advice: to achieve a relatively smooth walking pattern takes some time to nd a good combination of parameters.
Do not give up too fast, tweak the parameters and observe the results and - most of all - enjoy the fun playing with Robi!
Debug levels:
When the user interface starts it asks you to set the debug level. Typical settings are 0 or 1. You can set the debug level
later by using the command "d". Debug levels are:
0: only fatal errors and some important information is printed out
1: same as 0 including warnings and additional status information
2: full debug output
Remark: In all modules there are statements "if cfg.debug == <number>" . The number determines if a warning or status
is printed out or not, depending on the debug level set. You may change this number to output more or less debug
information.
A typical sequence for a test walk:
1. Enter command "i" to initialize the servos to their neutral position. Robi will stand straight on its feet.
2. Optionally: enter command "p" to change the walking parameters. When the program starts default
parameters are set, which are good for a rst test walk.
3. Enter command "r", this will move the CoM down to the ready position. From that position walking starts.
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 28
4. Enter "w" to start a test walk, based on the set parameters.
5. Command "." (dot) is used to repeat the last walk a number of times, so Robi will walk a certain distance.
Debugging:
During the project I collected some information on problems I observed and xes I implemented. Most of them I
mentioned in the Steps above. Here is a summary. If you nd additional problems and xes, please report through a
comment. I will update this Step.
Robi does not walk in a straight line or "stumbles":
Use command "i" to make Robi stand straight, check if all legs are perfectly aligned. If not, do a servo
calibration and change the o set for the re-aligned servo(s) in the module robi_def.py.
If Robi is well aligned, try to modify the parameters one at a time and observe the result. I found
combinations of CoM, step size and micro step width which work well and others which didn't.
Check the power supply, if it does not provide enough current the walking pattern is impacted.
If a servo rotates the wrong direction, change the rotation in module robi_def.py.
Poor Man's Bi-ped Robot Controller - Using RP2040 and Micropython: Page 30