Kaia.ai Firmware, ROS2 Configuration Files

Kaia.ai firmware works with a wide variety of ESP32 boards, supports robots of different sizes, with various Lidars, motors, motor drivers and motor encoders - all thanks to a
configuration file
where you can specify your GPIO assignments. Configuring Kaia.ai for your particular robot, board and its peripherals can be as easy as editing a text file called config.yaml
. Kaia.ai firmware loads and parses this config.yaml
file at boot time.
In this post I will present a config.yaml
example along with detailed explanations.
You can find more sample config.yaml
files for various ESP32 models and Maker’s Pet boards and robots here.
Follow instructions in the video below to upload your off-the-shelf or custom config.yaml
to ESP32 in Arduino.
Be sure to keep the indents formatting to make sure the firmware parses config.yaml
successfully.
Check the Arduino Serial Monitor at boot time for any parsing errors.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#
# Board-specific assignments
#
board:
manufacturer: makerspet.com
model: MINI-BDC30P-BODY with BDC-30P
version: v1.1.1
lidar:
gpio:
tx: 35
rx: 27
pwm: 13
en: 32
led:
system:
driver:
type: direct
gpio: 2
invert: false
button:
boot:
gpio: 0
invert: true
monitor:
gpio:
tx: 1
motor:
driver:
type: IN1_IN2
encoder:
type: AB_QUAD
left:
encoder:
gpio:
a: 39
b: 36
driver:
gpio:
in1: 26
in2: 25
right:
encoder:
gpio:
a: 17
b: 16
driver:
gpio:
in1: 23
in2: 22
adc:
battery:
attenuation: 7.0
gpio: 33
voltage:
full: 9.9
empty: 7.2
#
# Peripherals configuration
#
lidar:
model: LDROBOT LD14P
# model: NEATO XV11
# model: SLAMTEC RPLIDAR A1
# model: XIAOMI LDS02RR
# model: YDLIDAR SCL
# model: YDLIDAR X2
# model: YDLIDAR X2L
# model: YDLIDAR X3
# model: YDLIDAR X3 PRO
# model: 3IROBOTIX DELTA-2G
# model: 3IROBOTIX DELTA-2A 115200
# model: 3IROBOTIX DELTA-2A
# model: 3IROBOTIX DELTA-2B
# model: YDLIDAR X4 PRO
# model: YDLIDAR X4
scan:
freq:
target: 5.0
monitor:
baud: 115200
base:
wheel:
track: 0.105043
diameter: 0.043
accel:
max: 2.0
motor:
rpm:
# derated
max: 180
driver:
pid:
period: 0.03
kp: 0.001
ki: 0.003
kd: 0
kpm: 0
encoder:
ppr: 1035
Detailed Explanations
Let’s start with the board
top-level tag.
Here you can specify your board or DIY hardware name and version. Kaia.ai just prints out this information to Arduino Serial Monitor for identification purposes. The #
hash character comments at the beginning of a text line acts as a comment.
1
2
3
4
5
6
7
#
# Board-specific assignments
#
board:
manufacturer: makerspet.com
model: MINI-BDC30P-BODY with BDC-30P
version: v1.1.1
The lidar
top-level tag contains ESP32 GPIO assignments for the Lidar port. You can ignore this section if you don’t use a Lidar. If your Lidar does not have some of the pins listed below, you can leave those assignments unchanged (they will be ignored) or commend those lines out.
1
2
3
4
5
6
lidar:
gpio:
tx: 35
rx: 27
pwm: 13
en: 32
The led
top-level tag contains the system LED GPIO configure. The configuration example below is specifically for 30-pin ESP32 DOIT DevKit v1 modules that have an integrated LED connected to GPIO2. Other ESP32 modules may have a different GPIO LED assignment, a different type of LED (serial instead of driven directly by the GPIO) or may not have an integrated LED at all. You can find and reuse examples for various ESP32, ESP32S3, ESP32E, Arduino ESP32S3 Nano boards here https://github.com/kaiaai/firmware/tree/iron/kaiaai-esp32/data.
1
2
3
4
5
6
led:
system:
driver:
type: direct
gpio: 2
invert: false
The button
configuration assigns a GPIO to the BOOT
button for the 30-pin ESP32. The choice of this GPIO may vary across ESP32 modules and boards. See https://github.com/kaiaai/firmware/tree/iron/kaiaai-esp32/data for examples.
1
2
3
4
button:
boot:
gpio: 0
invert: true
monitor
assigns a GPIO to the Arduino Serial Monitor (30-pin ESP32 boards in this example).
1
2
3
monitor:
gpio:
tx: 1
motor
specifies the motor driver and motor encoder types. Simply speaking, Kaia.ai firmware supports two motor types:
- brushed DC with motor (driver type
IN1_IN2
) with quadrature encoder (encoder typeAB_QUAD
). This type of motor (popular low-cost N20, JGA25, etc.) haveMOTOR+
andMOTOR-
motor inputs, directly driven usually by L298N, TB6612FNG or similar driver ICs that haveIN1
andIN2
inputs. The quadrature encoderAB_QUAD
has two outputsA
andB
(sometimes namedC1
,C2
or similar). - brushless DC motor with built-in ESC controller. Motors like this (driver type
PWM_CW
, encoder typeFG
) havePWM
(speed) andCW
(rotation direction) inputs andFG
encoder output.
1
2
3
4
5
motor:
driver:
type: IN1_IN2
encoder:
type: AB_QUAD
Here is where you assign GPIO input to track the left motor quadrature encoder. If your motor is brushless with fg
output, specify the GPIO number associated with FG
. For example, fg: 39
.
1
2
3
4
5
left:
encoder:
gpio:
a: 39
b: 36
Here is where you assign GPIO outputs to your brushed motor driver IC (L298N, TB6612FNG, etc.) or to your brushless motor with built-in driver (using pwm: xx
and cw: xx
).
If your motors don’t seem to work during your robot bring-up - including not rotating, rotating in the wrong direction and rotation never stopping - check the driver and encoder GPIO assignments. In particular, check if driver in1
and in2
GPIO assignments need to be swapped. Same goes for encoder a
and b
GPIO assignments.
1
2
3
4
driver:
gpio:
in1: 26
in2: 25
Set your GPIOs for the right motor here.
1
2
3
4
5
6
7
8
9
right:
encoder:
gpio:
a: 17
b: 16
driver:
gpio:
in1: 23
in2: 22
Optionally, in the adc
section, assign a GPIO analog input to track the battery voltage. If your battery voltage higher than what ESP32 GPIO can handle, you can use a resistor divider to attenuate the battery voltage. For example, if you are using a 9V battery, you can make a resistor divider that divides the battery voltage 7x before feeding it to the ESP32 ADC GPIO input. The full and empty battery voltage settings help calculating the percentage of charge left in the battery.
1
2
3
4
5
6
7
adc:
battery:
attenuation: 7.0
gpio: 33
voltage:
full: 9.9
empty: 7.2
So far we have configured the board-related assignments. The rest of the file configures the robot-related parameters.
In the lidar
section, choose your Lidar model from the list of supported sensors and set the desired scan speed (if supported by firmware and your Lidar). If you are not using a Lidar, just leave this section unchanged.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#
# Peripherals configuration
#
lidar:
model: LDROBOT LD14P
# model: NEATO XV11
# model: SLAMTEC RPLIDAR A1
# model: XIAOMI LDS02RR
# model: YDLIDAR SCL
# model: YDLIDAR X2
# model: YDLIDAR X2L
# model: YDLIDAR X3
# model: YDLIDAR X3 PRO
# model: 3IROBOTIX DELTA-2G
# model: 3IROBOTIX DELTA-2A 115200
# model: 3IROBOTIX DELTA-2A
# model: 3IROBOTIX DELTA-2B
# model: YDLIDAR X4 PRO
# model: YDLIDAR X4
scan:
freq:
target: 5.0
Set the Arduino Serial Monitor baud rate in the monitor
section.
1
2
monitor:
baud: 115200
base.wheel.track
specifies the istance between your wheels in meters. More specifically, it is the distance between the midpoints of your tires.
1
2
3
base:
wheel:
track: 0.105043
base.wheel.diameter
specifies your outer wheel (tire) diameter in meters.
1
diameter: 0.043
base.wheel.accel.max
sets your robot’s maximum allowed acceleration. For example, increase the acceleration if your robot motors and power supply can handle the load.
Decrease the max acceleration if
- your robot wheels slip
- your motors are not powerful enough (for the given robot’s weight) to achieve the max acceleration
- your motor driver or motor power supply cannot supply enough current
1 2
accel: max: 2.0
motor.rpm.max
sets your motor maximum RPM (revolutions per minute) taken from your motor’s datasheet and derated (i.e. multiplied by ~0.9). The derating factor is necessary because the actual max RPM varies from motor to motor. Therefore, letting both motors run at their max RPM without derating often causes the robot veer off the straight path.
1
2
3
4
motor:
rpm:
# derated
max: 180
Kaia.ai firmware controls motors using a PID controller. Set the PID controller coefficients in the motor.driver.pid
section. Check these settings if your motors lag or oscillate. motor.driver.pid.period
is how often the PID gets updated, in seconds. kp
, ki
, kd
and kpm
are the proportional (AKA proportional-on-error), integral, derivative and proportional-on-measurement gain coefficients respectively. PID tuning is a topic worth a separate post.
1
2
3
4
5
6
7
driver:
pid:
period: 0.03
kp: 0.001
ki: 0.003
kd: 0
kpm: 0
Lastly, motor.driver.encoder.ppr
sets the the number of pulses the motor encoder outputs per one rotation of the motors shaft (i.e. the motor gearbox output).
1
2
encoder:
ppr: 1035
Configure LiDAR model in ROS2
As of March 2025, if your robot’s LiDAR model differs from the default one provided in the Kaia.ai Docker image (e.g. LDROBOT LD14P
for Maker’s Pet Mini), you will need to edit the ROS2 configuration - in addition to editing config.yaml
as described above.
Here are steps to change the default LiDAR model.
- Launch a
kaiaai/kaiaai:iron
Docker container as described here - edit Maker’s Pet Mini telem.yaml file in the Docker Bash shell
1
pico /ros_ws/src/makerspet_mini/config/telem.yaml
- change
lidar_model: "LDROBOT-LD14P"
to one of the compatible LiDAR models:YDLIDAR-X4
,XIAOMI-LDS02RR
,YDLIDAR-X2-X2L
,YDLIDAR-X3-PRO
,YDLIDAR-X3
,NEATO-XV11
,SLAMTEC-RPLIDAR-A1
,3IROBOTIX-DELTA-2G
,3IROBOTIX-DELTA-2A
,3IROBOTIX-DELTA-2B
,LDROBOT-LD14P
,CAMSENSE-X1
,YDLIDAR-SCL
- for example,
lidar_model: "3IROBOTIX-DELTA-2G"
- save the edited file (Ctrl-X, Y, Enter)
- back up your
telem.yaml
because your changes will be lost once the Docker container is destroyed
1
cp /ros_ws/src/makerspet_mini/config/telem.yaml ~/maps/
- restore your modified
telem.yaml
file - or persist it permanently as described later in this post - next time you launch a new Kaia.ai container
1
cp ~/maps/telem.yaml /ros_ws/src/makerspet_mini/config/
Configure Custom Robot Size in ROS2
If your robot’s base dimensions differ from the default ones provided in the Kaia.ai Docker image (e.g. Maker’s Pet Mini, Loki, Fido or Snoopy), you will need to edit the ROS2 robot configuration as well.
cd /ros_ws/src/makerspet_mini/config
- edit these files to specify your custom robot’s parameters
- in
teleop_keyboard.yaml
set your robot’s maximum and minimum linear and angular speed limits and steps - in
telem.yaml
set the battery voltage range - in
/ros_ws/src/makerspet_mini/urdf/robot.urdf.xacro
set your robot’swheel_base
,base_diameter
,wheel_diameter
andwheel_width
.
- in
- back up your edited files
- restore - or persist permanently as described below - your edited files when you launch a new container
Optionally, Persist Your ROS2 Configuration Changes
If you need to keep your changes permanently in the Docker image, you will need to build your own Docker image for your custom robot. Here are kaiaai/kaiaai
Docker image build scripts for your reference.
Detailed instructions TODO.