Monday, July 21, 2025

S3GWAY: Self-Balancing LEGO EV3 Robot with Trajectory Tracking

Show post in language: English, Русский

This project documents my journey in building self-balancing Segway-like robots based on LEGO Mindstorms sets (NXT and EV3), with a focus on advanced control theory, including state observers, Kalman filtering, \(H_2\)/\(H_\infty\) controllers, and trajectory tracking. It is intended for robotics enthusiasts interested in control theory.

My interest in self-balancing robots began with models like NXTWay-GS and HTWay after the release of the LEGO Mindstorms NXT set. I used a HiTechnic gyroscopic sensor and programmed the robot with Java using the LeJOS firmware. With the release of Lego EV3, the project was redesigned using the new platform and the LeJOS EV3 firmware. I used the Gyroboy Matlab Project and Balanc3r as a reference.

However, all these models used numerical differentiation and integration to reconstruct the unmeasurable elements of the robot's state vector. I wanted to implement a controller using a state observer. Another challenge for me was the desire to study and apply \(H_2\) and \(H_\infty\) controllers. I hoped they would help solve the instability issues encountered when using an observer.

When the Xiaomi MI MITU builder kit came out, which can move along a trajectory drawn on a smartphone screen, I wanted to implement this feature as well.

The developed control algorithm allows the robot to follow a given trajectory, but for now, I define the trajectory through an algorithm rather than by drawing on a smartphone screen. Maybe in the future, I’ll implement that too.

I used EV3 medium motors because they have less backlash, and I initially thought that the observer wasn't working due to the large backlash in the gearboxes. Eventually, I managed to adapt the controller for EV3 large motors.

Previously, I had measured the parameters of the large motors, but for the new robot, I needed to estimate the parameters of the medium motors. This time, I used current and voltage sensors to more accurately measure motor parameters.

During the project, I became dissatisfied with the performance of the Java platform, as programs took a long time to start and the control loop intervals were not stable. So, I ported part of the LeJOS EV3 library to C++, which allowed me to use the same firmware as LeJOS. The similarity in class structures made it possible to transfer my work to the new platform without major modifications. I built a cross-compiler for Lego EV3 using Crosstool-NG.

As a gyroscopic sensor, I used a previously developed IMU based on the LSM6DS3. The problems described in this and this post were not observed with my sensor.

During the research, I studied the Kalman filter, learned how to synthesize a reduced-order Luenberger observer, studied the synthesis of \(H_2\) and \(H_\infty\) controllers, and learned how to add an integrator and gyroscope drift estimation to an \(H_\infty\) controller — which is a non-trivial task.

I implemented two variants of trajectory tracking control: a nonlinear controller based on Lyapunov functions and a feedback linearized controller.

I did not prepare assembly instructions for the robots but did create CAD model files with medium and large motors.

The description is provided in two files: motor parameter estimation and controller synthesis.

Этот проект описывает мои эксперименты по созданию балансирующих Segway-подобных роботов на основе наборов LEGO Mindstorms (NXT и EV3), с акцентом на продвинутую теорию управления, включая наблюдатели состояния, фильтр Калмана, \(H_2\)/\(H_\infty\) регуляторы, траекторное управление. Он предназначен для любителей робототехники, интересующихся теорией управления.

Мой интерес к балансирующим роботам начался с моделей NXTWay-GS и HTWay после выхода набора LEGO Mindstorms NXT. Я использовал гироскопический датчик HiTechnic и запрограммировал робота на Java с помощью прошивки LeJOS. С выходом Lego EV3 проект был переработан с использованием новой платформы и прошивки LeJOS EV3. В качестве образца я использовал Gyroboy Matlab Project и Balanc3r.

Но все эти модели использовали численное дифференцирование и интегрирование для восстановления неизмеряемых элементов вектора состояния робота. Хотелось реализовать регулятор с использованием наблюдателя состояния. Ещё одним вызовом для меня было желание изучить и применить \(H_2\) и \(H_\infty\) регуляторы. Я надеялся, что они помогут решить проблемы с нестабильностью робота при использовании наблюдателя.

После появления набора Xiaomi MI MITU builder, который может двигаться по нарисованной на экране смартфона траектории, мне захотелось реализовать эту возможность.

Разработанный алгоритм управления позволяет роботу ехать по заданной траектории, но саму траекторию я пока задаю в виде алгоритма, а не по рисунку на экране смартфона. Возможно, в будущем, я реализую и это.

Я использовал средние моторы EV3, т.к. у них меньше люфт, а я изначально думал, что наблюдатель не работает из-за большого люфта в редукторах. В итоге, мне удалось адаптировать регулятор под большие моторы EV3.

Ранее, я измерял параметры больших моторов, но для нового робота нужно было оценить параметры средних моторов. В этот раз я использовал датчики тока и напряжения для более точного измерения параметров моторов.

По ходу реализации проекта меня перестала устраивать производительность платформы Java, т.к. программы долго запускались, и стабильность интервалов управляющего цикла оставляла желать лучшего. Поэтому я перенёс часть библиотеки LeJOS EV3 на C++, что позволило мне использовать ту же прошивку, что и для LeJOS. Схожесть структуры классов позволила перенести мои наработки на новую платформу без больших переделок. Кросс-компилятор для Lego EV3 я собрал, используя Crosstool-NG.

В качестве гироскопического датчика я использовал ранее разработанный IMU на базе LSM6DS3. Проблем, описанных в этом и этом сообщениях, с моим датчиком замечено не было.

В ходе исследований я разобрался с фильтром Калмана, научился синтезировать наблюдатель Люенбергера пониженного порядка, изучил синтез \(H_2\) и \(H_\infty\) регуляторов, научился добавлять интегратор и оценку дрейфа гироскопа в \(H_\infty\) регулятор, что является нетривиальной задачей.

Реализовал два варианта траекторного управления. Нелинейный регулятор на базе функций Ляпунова, и регулятор, линеаризованный обратной связью.

Инструкций по сборке роботов я не делал, но подготовил CAD файлы моделей со средними и большими моторами.

Описание я разместил в двух файлах: измерение параметров двигателей и синтез регулятора.

Thursday, July 7, 2016

UART IMU sensor for EV3

Some time ago I made a Segway-like robot using Lego NXT set. I based it on this mathematical model. The controller used the control loop with 8 ms period, so it required the gyroscope sensor that could read samples faster than 8 ms. I had two gyroscope sensors: Hitechnic Gyro Sensor and Mindsensors AbsoluteIMU.
Hitechnic sensor is an analog one and it can produce samples very fast, but it has significant drift and that depends on the battery voltage (see this post). AbsoluteIMU is a 3-axis sensor that produce more accurate measurements, but it is an I2C sensor that works quite slow on NXT and EV3 platforms. Reading sample time is about 25 ms.
Fortunately, there is a way to speed up I2C bus on NXT platform. LeJOS for NXT can turn I2C sensor to high-speed mode where reading sample time is about 2 ms.
But when I ported my code to EV3 platform, I found that high speed I2C support work incorrectly on EV3. So I could use the sensor in low-speed mode only. It was about a year ago.
I wanted an IMU that combines gyroscope and accelerometer and would be able to read samples faster that 8 ms.
EV3 supports new UART sensors that can support very high communication speed (up to 460 kbit/sec). I have found an article that can be a good starting point to create own UART sensors for EV3.
But I wanted to have a complete device that can be mounted to Lego robot, so I needed to fit it into the an existing Lego sensor case. I used Lego Light Sensor as a case for my IMU sensor.
During working on the sensors I tested three IMU chips: LSM330DLC, LSM9DS0 and LSM6DS3.
The first one is a cheap 6DOF sensor, the second one is a 9DOF sensor (I want to tests 9DOF sensor fusion algorithm on it), and the last one is a low-noise 6DOF sensor.

Sensors use UART speed 115200 bps to be compatible with EV3 Soft-UART ports 3 and 4. Ports 1 and 2 allow to use speed up to 460800 bps. But due to a bug in EV3 firmware it actually uses frequency 485294 bps, so it is necessary to use this value to be able run UART in hi-speed mode (in sensor descriptor we should specify speed 460800, but set uart speed to 485294).  I have prepared a class uart_speed that calculates correct UART speed, compatible with EV3.

Monday, March 23, 2015

Mathematical Model of Lego EV3 Motor

Some time ago I calculated Lego NXT motor parameters to use them in mathematical modeling of Lego motor. Also I used them to calculate controller constants for Segway-like robot.
When I bought Lego EV3 set, I wanted to port my Segway program to EV3. But I need to build EV3 motor model to calculate balance controller constants. In this post I described how I measured and estimated the motor's parameters.

Thursday, October 4, 2012

Laser Sensor for Lego NXT

This sensor was made for experiments with triangular localization.
 For triangulation  we need to have three beacons and a sensor that can detect beacons. The laser sensor seems as the best solution for this experiment.

Friday, January 14, 2011

Motor controller with feed-forward for Lego NXT

Goals
During experiments with Java version of Lego motor controller and built-in LeJOS motor controller I found that they use different approaches to implement smooth acceleration. Lego controller uses integer arithmetics and implements non-linear acceleration algorithm. It divides the acceleration distance to the speed delta and gets the interval to increase speed for 1 degree/sec. Each time when the motor covers the interval, the controller increases its speed for 1 degree/sec. This algorithms is simple but acceleration is non-linear. LeJOS uses different approach. The version I tested had problems with smooth acceleration. But LeJOS team has published an updated version of motor controller that works well. This version implements linear acceleration approach using floating point arithmetic. Also LeJOS controller uses much smalled discretization interval (interval between regulation cycles). Lego controller uses 100ms interval, LeJOS controller uses 4ms interval. This small regulation interval has some advantages and disadvantages: it provides more fast reaction to change of external load but requires more CPU time, especially being implemented in Java. Lego controller is implemented in native ARM code and works faster.

I wanted to make a controller that has best qualities of LeJOS controller but requires less CPU time. I tried to increase discretization interval but found that this controller has problems with rotation to a specified angle. It could not reach the target position with zero speed and requires additional time to reach the target point.

Saturday, November 27, 2010

Compare motor controllers of LeJOS and Lego firmware

In this post I'm going to compare two motor controllers: from Lego Mindstorms firmware and from LeJOS class library. I use LeJOS in my robot programming, because it much more powerful than other programming languages I used (NXT-G, NXC). But I found a strange behavior of the motor controller in my last project and wanted to study how it works and compare it to PID-controller from default Lego firmware.