HTWay – A Segway type robot

Introducing the HTWay, a Segway type self-balancing robot. This robot uses the HiTechnic Gyro Sensor as well as the HiTechnic IRReceiver. The Gyro sensor is used to maintain balance while the IR Receiver allows it to be controlled with a LEGO Power Functions remote.

Building Instructions for the HTWay
NXT-G Program for LEGO Mindstorms 2.0
NXC Program (version 1.1)

Update(Nov 8, 2010):The NXC version was updated to fix a bug that caused the program to crash when the optimization level was set beyond 1.
Update(July 28, 2010):The NXT-G Program in the download above has been updated to use the new 2.0 Gyro sensor block available for download from the Downloads page. If you are using the original 1.0 Gyro sensor block, you must update it to the new 2.0 block for use with this program.

Both the NXC and NXT-G programs work essentially the same way. The programs take advantage of floating point math that is new with LEGO Mindstorms NXT 2.0. The original 1.0 NXT only supported integer math. While using floating point math is not essential when programming a Segway type robot, it makes the program much easier to understand and to work with.

Update for NXT-G: For the NXT-G program, make sure you also download and install the Gyro and IR Receiver blocks from the LEGO Mindstorms software. You can find the them on the Mindstorms NXT-G Blocks downloads page.

If you usually program in NXT-G with LEGO Mindstorms 1.0 or 1.1, then this is a great opportunity to give NXC a try. If you install the development environment BricxCC, you will get NXC as part of the package. For the HTWay you will also need LEGO firmware 1.26 or higher. I recommend LEGO Firmware 1.29. This firmware is fully compatible with the earlier version and will still work with your LEGO Mindstorms 1.0 and 1.1 software. You can even use BricxCC to download the firmware to the NXT; from the Tools menu, select Download Firmware. You will also need to make the NXC compiler target the 2.0 firmware to take advantage of the floating point math. You can do that by going to Edit->Preferences, then click on the Compiler tab and then the NBC/NXC sub-tab. Now check the option for “NXT 2.0 compatible firmware”.

Update for NXC: In order to take advantage of the floating point math support you will also need to download and install the latest test release of BricxCC. After you download the zip file of the test release, copy the contents over your existing BricxCC installation. This will most likely be c:\Program Files\BricxCC.

When you run the program, the first thing it will do is let you select the wheel size that you are using. There are three options: Small (NXT 2.0), Medium (NXT 1.0), and Large (RCX). Use the arrow keys to choose and the Orange Enter button to select.

The robot will now need to get an initial gyro offset. You can think of this as a Gyro Sensor calibration. In order to get a good gyro offset, the robot will need to be copletely still. If you hold the robot in your hand it will wait until you you put the robot down, and it is not moving, before it will get the gyro offset and go on. HTWay will now start beeping indicating that you have five seconds to get the robot vertical and as balanced as possible. At the end of the long beep, let go.

The robot should now be balancing and is ready to be driven with the LEGO PF remote. You can control it like you would a tank. Both levers forward and the robot drives forward. Both lever back and it reverses. One lever only and it will turn around one stopped wheel and both levers in opposite directions and it will turn in place.


This is a classic problem in control theory. Prior to the Segway Personal Transporter, it was more commonly known as the inverted pendulum problem. Normally when you think of a pendulum, like on a clock, it hangs down below the pivot point where it is stable; the inverted pendulum is one where the center of gravity is above the pivot point in a position that is inherently unstable. To keep it up, the pivot point has to move to catch it when it begins to fall. That is in essence the same problem as making a segway robot balance.

LegWayWith LEGO robotics, this challenge has been taken up many times. First came Steve Hassenplug’s LegWay using the RCX and two EOPD sensors. These RCX EOPD sensor were early HiTechnic products that functioned essentially the same as the current NXT EOPD sensors. These sensor were used to tell the distance to the floor. If the robot was leaning forward, then the sensors would be closer to the floor so the RCX could tell that it was leaning forward. If it leaned back, then the sensors would be further away from the surface. This was a fantastic creation and Steve even got a place on cable TV fame with this amazing robot. Not only could it balance exceptionally well, it could line track and even spin in circles to impress the crowds.

LegWayWith the NXT, Philippe E. Hurbain built the NXTWay using the NXT Light Sensor in a way similar to Steve Hassenplug’s LegWay. Under controlled conditions, the LEGO Light sensor can also be used to tell distance. As long as lighting and surface are consistent, the robot can tell if it is leaning forwards or backwards based on the light sensor value. Given the poor resolution of the light sensor, this was an impressive accomplishment.

The first gyro sensor based NXT Segway robot came from Ryo Watanabe at Waseda University in Japan. The original HiTechnic YouTube video of a balancing robot was in fact Ryo Watanabe’s very impressive robot that was using, at the time, a prototype HiTechnic Gyro Sensor. Ryo did an amazing job of describing the physics and his solution that were very valuable in the creation of the current HTWay model.

Segway with riderMore recently Dave Parker at created an amazing NXT 2.0 one kit Segway with rider robot using the LEGO Color sensor in a similar way to Philo’s NXTWay. Dave Parker came up with the original idea of using the third motor to offset the balance and to it use to make the robot go forwards or backwards, in a way similar to the real Segway PT which is also controlled by the human rider leaning forwards or backwards. Very cool!

AnyWayLaurens Valk has also recently published a Segway type robot that uses the HiTechnic Gyro Sensor. He calls his creation the AnyWay. Like the HTWay, his program is also written in NXT-G. Laurens’s project inspired some ideas that were used in the creation of the HTWay including the idea of letting the user choose wheel size with the button interface in the beginning of the program.

How it works

First of all, you don’t have to understand exactly how it works to make this robot. You can build it and put the NXC or NXT-G program on it and have fun with it even if you don’t fully get the math that makes it balance. Both the NXC and NXT-G programs are written such that the control code is separate from the balance code. If you want to use other sensors, such as the Ultrasonic or Light sensor, in addition to the Gyro sensor that is essential for balancing, you can do that. All you need to do is have your own control code which can in turn drive the robot by changing two global variables, motorControlDrive and motorControlSteer in NXC and controlDrive and controlSteer in NXT-G. Both of these variables are in degrees per second. The steering control is based on the desired difference in the motor encoders.

Above you will find the download links for both NXC and NXT-G programs. These programs have been written so that they work as much as possible the same way. Below I give some code snippets from the NXC program. If you are a NXT-G programmer, try to follow along. You can also look at the actual NXT-G code in the LEGO Mindstorms software and follow along there. Since some of the math equations get quite big in NXT-G, it may be easier to understand the NXC program.

In order to balance, the robot has a control loop which takes four pieces of information into account and then decides how much motor power is needed to stay upright. In a simplified form, the NXC code for the main balance loop looks like this:

  while(true) {
     GetGyroData(gyroSpeed, gyroAngle);
     GetMotorData(motorSpeed, motorPos);

     power = KGYROSPEED * gyroSpeed +
             KGYROANGLE * gyroAngle +
             KPOS       * motorPos  +
             KSPEED     * motorSpeed;

     OnFwd(LEFT_MOTOR, power);
     OnFwd(RIGHT_MOTOR, power);

Note that the real NXC program is a little more complicated because it takes a few more things into account such as driving, steering and the fact that the motor power needs to be limited to a +/- 100 range.
In this code fragment you can see that every time through the balance loop, four pieces of data are obtained: gyroSpeed, gyroAngle, motorSpeed, and motorPos. These are the state variables that describe what is currently happening to the robot.

gyroSpeed is from the Gyro Sensor and is the angular velocity of the robot. If the robot is in the middle of falling forward, then this value will be positive. The units are approximately in degrees per second.
gyroAngle is the angle of the robot. This value is positive if the robot is leaning forwards, and negative if leaning backwards. (This is not exactly true as will be explained later) The units for gyroAngle is degrees.
motorPos is the position of the robot in degrees of the motors. For the HTWay, this is actually the sum of the two motor encoders. This is the term that keeps the robot in a particular place.
motorSpeed is the speed of the motors. This number is also in degrees/second and is also based on the sum of the two motor encoders. This term is what keeps the robot from excessively oscillating back and forth and effectivly slows it down.

To calculate the power these variables are multiplied by respective constants in a four term linear equation, the result being the power needed for the robot to stay balanced. The trick to making this all work, is finding the right constants.

To give you an idea of the role of each term in the balance equation, I will talk about each term one at a time with an attempt to isolate what each one does. First of all, imagaine that the robot is perfectly balanced and exactly at the desired target position. In that case, all four of the variables will be zero. In other words, the robot is perfecty vertical so the gyroAngle is zero, the robot is not falling forwards or backwards, the robot is not moving and it is exactly in the desired position. Since all four variables are zero, the result of the power equation is also zero.

So what if the all the terms are zero except that the robot is leaning forwards, for example the gyroAngle is 5 degrees. What to do? Well if the robot is leaning forwards, then it is necessary to drive forwards to attempt to catch the robot. That is is the role of the KGYROANGLE constant. When multiplied with the gyroAngle, it will give the power needed to drive forwards to catch the fall to regain balance.

Again, imagine all the terms are zero except that this time the gyroSpeed is positive, perhaps it is 10 degrees/second. So the robot is upright and not moving, but it has somehow gotten itself into a situation where it is falling forwards. In a way you can think of this as a head’s up that things are going astray. Even though it is upright now, it is about to be leaning forwards. This term lets the robot respond even before it falls forward. It also plays a role when the robot is leaning but is on its way to becoming upright, in that case this term will prevent the gyroAngle term from making the robot respond when in fact its okay.

So what about the two motor terms? Well if the robot is perfectly upright and not falling but the robot is 100 degrees further forward then desired, in that case motorPos will be 100. Remember, motorPos in the HTWay program is the sum of the two motor encoders. The actual distance of how far forward it is will also depend on the wheel size. While it would be nice to just drive back to the zero position, that doesn’t work. If you attempt to just drive backwards back to the zero position, then the robot would actually fall forwards. The solution is actually to drive forwards, because in order to go backwards, you first have to get the robot to fall backwards. To do that, you drive forwards!

The motorSpeed term works in sort of the the same way as motorPos. If the robot is in the middle of driving forwards, then first of all you need at least enough power to maintain the speed, and thus the balance, and then you even need a little more to get the robot to lean backwards to make it slow down.

In the NXC program, the four constants are set to these values near the top of the program:

#define KGYROANGLE  7.5
#define KGYROSPEED  1.15
#define KPOS        0.07
#define KSPEED      0.1

A note about wheel size making it go
In the HTWay program you can select the wheel size you are using with a three button interface. What this does is it sets a global variable called ratioWheel to either 0.8, 1.0, or 1.4 for respectively the small NXT 2.0 wheels, the medium sized NXT 1.0 wheels and or the large RCX wheels. So what does this actually do? Well the actual balance equation is a little different then what was shown above, here is the full expression used in the program:

     power = (KGYROSPEED * gyroSpeed +
              KGYROANGLE * gyroAngle) / ratioWheel +
             KPOS       * motorPos +
             KDRIVE     * motorControlDrive +
             KSPEED     * motorSpeed;

It turns out that the wheel size only needs to play a role with the two gyro sensor terms and not the motor terms. The reason that wheel size is important is because bigger wheels need less power to compensate for being out of balance. Since bigger wheels move further, given a certain amount of input, you need less of it to achieve the same amount of movement. So why not take the wheel size into account on the motor terms? The reason is that these terms are effectively self-relative. If the robot is, for example, one inch too far forwards, then this will be represented by a higher motorPos value for small wheels than for big wheels. Effectively, for the small wheeled robot this will result in a higher influence on the motor power than what will happen for the same distance using the bigger wheels.

In the code above you will also see that the motorControlDrive also plays a role in the balance equation, this is not actually what drives the robot. This term is used to help get the robot going as well as to slow it down whenever the motorControlDrive term changes. When you start driving the robot, this term will cause the robot to first drive backwards a little to quickly get going, then when you stop it will give the robot a little extra boost to help it lean back to slow down. The actual driving comes from this line right above the power balance equation:

     motorPos -= motorControlDrive * tInterval;

Every time through the loop, the motorPos variable is adjusted proportionally to the global variable motorControlDrive. motorControlDrive is in degrees/second so by multiplying it by the interval time, we are adjusting the motorPos by the amount that the robot should move each time through the control loop. This moves the target position along which is what makes the robot drive.

If you are a young robot builder, you have probably never heard of integration. If you are older, you probably wish you never had. It turns out that integration is really useful and essential for this project. And actually not that hard to understand.

The problem is that the Gyro Sensor does not give you an actual angle. You can’t just read the Gyro Sensor and tell if the robot is leaning forwards or backwards. All you can tell is the angular velocity, in other words, how fast it is falling. So if you know the angular velocity, how can you get an angle? Well that’s what integration does.

Integration is simply the act of adding an infinite series of values over time. Let’s say that at a given time you know the robot angle, we keep that in a variable called gyroAngle. Each time through the loop we get from the Gyro Sensor the angular velocity in degrees/second. So if we know the interval of the loop, then we can update our gyroAngle by the amount that we know the angle has changed. Since our loop is running at about 100 times per second, the interval time is 0.01 seconds. To update the gyroAngle, we simply add the gyroSpeed times the interval time (0.01 seconds) into the gyroAngle to get a new value. That’s it!

Here is the NXC function for getting the gyro data that does this:

void GetGyroData(float &gyroSpeed, float &gyroAngle)
  float gyroRaw;

  gyroRaw = SensorHTGyro(GYRO);
  gOffset = EMAOFFSET * gyroRaw + (1-EMAOFFSET) * gOffset;
  gyroSpeed = gyroRaw - gOffset;

  gAngleGlobal += gyroSpeed*tInterval;
  gyroAngle = gAngleGlobal;

This function also takes care of one more piece of housekeeping that we should discuss: the gyro offset. Because the technology of the gyro sensor element, the raw sensor value is likely to be non-zero even when the sensor has no actual angular velocity. Since we need a zero value when the sensor is not turning, we need to maintain a gyro offset value that we can use to adjust the sensor value to get an accurate angular velocity.

To maintain a gyro offset the program does two things. Before the robot starts to balance it gets an initial gyro offset by averaging 100 samples of the sensor value while the robot is lying on the ground. But this value will just be the initial gyro offset. While the robot is driving we will also need to constantly adjust this offset value in order to keep the value from drifting with time (and as a result the whole robot will drift in position if not corrected). In the HTWay program, this is done by maintaining a long term average known as Exponential Moving Average. Since the long term average of the angular velocity, assuming the robot is balancing, should be zero, the long term average of the sensor value can be used as the gyro offset.

In the code above, EMAOFFSET is very small, 0.0005, so even if the robot is moving back and forth while balancing, it will not have a large immediate effect on the gOffset value. Only if the offset is off over a significant period of time will the offset value get noticeable changed. This way of using an exponentially moving average is also known as a low-pass filter.

gyroAngle and motorPos… not exactly zero
When the robot starts balancing, the program assumes the robot is vertical. Well, even if you are really good when you let go of the robot, this may not be true. You are likely to be off by a degree or two. Also, even though the program maintains a gyro offset and is constantly integrating the angular velocity to maintain gyroAngle, this may not be perfect and the gyroAngle may still drift a bit with time. Sounds like a disaster, no? It turns out to not be a problem. The reality is that when you are not driving and the robot is gently oscillating back and forth maintaining balance, the gyroAngle and motorPos can be proportionally away from zero. The reason it works is because the two terms have reached an equilibrium where one offsets the other. For example, the robot may be nicely balanced around a gyroAngle value of 1 degree, to compensate, motorPos may be around -107 degrees. When these two values are multiplied by their respective constants in the balance equation, they will cancel each other out.


Ryo Watanabe did an excellent job of explaining both the physics of the problem and the linear equation that makes a solution possible on the NXT. Here is the overview.

Another good website with information about LEGO Segways programming is


I would like to thank Laurens Valk and Xander Soldaat who helped me with this project. Xander reviewed the building instruction and tested the robot. Laurens and I discussed various aspects of the program which influenced some features such as how the gyro offset is maintained as well as the feature of allowing the user to select the wheel size at the beginning of the program.

“Segway” is a registered trademark of Segway, Inc.

Tags: , , , , ,

97 Responses to “HTWay – A Segway type robot”

  1. Hunter Chiou says:


    Thanks for your program and tutorial.

    May I compile your rbtx file to rxe file, and share it to others who has no NXT-G 2.0 software?

    Some of my readers wants to make HTway, but they ony have 9797 with NXT-G 1.0.

    I will put the rxe filw in

    Thank you!

  2. Gus says:

    You are welcome to do that. In fact I thought it was a good idea so I went ahead and added the complied HTWayG.rxe file to the file download. You will also have to tell your readers that in order to run this program on their NXT, they will need to download and install the LEGO firmware associated with LEGO Mindstorms 2.0, such as Firmware 1.29. The programs will not run on their 1.0 firmware since there is no floating point support on the older NXT firmwares.

  3. [...] If you want to build a balancing robot, there is no shortage of options to chose from.  There’s the original LegWay, NXTWay, SegWay with Rider and more recently the AnyWay.  If you thought that wasn’t enough, Gus from HiTechnic has made another, called the HTWay.  [...]

  4. Brian says:

    I am guessing that there is going to be a spike in sales for the IRReceiver. Great job on the HTWay, I can’t wait to build this and try it out. Is there room in the current design to use the NXT rechargeable battery pack without modification? Thanks again.

  5. Gus says:

    Brian, Thank you! Yes, the NXT rechargeable battery pack fits on HTWay.

  6. [...] omniwheel, Laurens’ Snatcher from his new book, the HTWay and some other [...]

  7. nxtman says:

    hi, i have a competeition and NEED the 1.0 download. when i went to the site the has it (above) it was in chinese (or japanese or something) i couldn’t read it. where is another way to download a nxt-g filein nxt-g 1.0
    i have firmware 1.29 but software(computer) 1.1. help

  8. Gus says:

    The zip file for the NXT-G 2.0 program, also includes a compiled rxe file. If you have LEGO Mindstorms 1.0, one alternative is to download HTWayG.rxe directly to the NXT as long as the NXT has a firmware of 1.26 or later (1.29 is recommended). Extract the rxe file form the zip file. From the LEGO 1.0 software, click on the NXT Window button on the lower right corner of the screen (top left of the five buttons). Then click on the Memory tab. Then click on the Download button. You can now browse to the expanded HTWayG.rxe file and download it to the NXT.

  9. Alex says:

    I tried to make this work but I can’t…
    With BricXcc I can’t find the option for “NXT 2.0 compatible firmware”.
    NXT-G (edu version) just says “The program is broken. It may be missing required files.”
    I have a 2.0 NXT with 1.29 FW
    Please HELP !
    I wouold prefer the NXC version of the program but BricxCC says
    Error: Preprocessor macro function does not match instance (asm {
    what does that mean?

  10. Alex says:

    Thanks Gus
    I downloaded the test release of BricxCC and now everything works just fine
    Thanks again

  11. Gus says:

    For the NXT-G program you also need to download and install the NXT-G blocks for the Gyro Sensor and the IR Receiver. You can find those on the downloads page.

    For BricxCC/NXC, you will need to download and install the test_release in order to get the floating point math support. You can find the test_release the BricxCC page.

  12. Lalom says:


    I’m from Thailand with NXT. My son will has challenge soon and currently we’ve got 1 Gyro sensor and trying to build 1 HTway but the challenge rule is the robot has to run by itself following the strip line. Can we build it with Gyro + other sensor instate of IR sensor? If can how can we apply the program that you provided.


  13. Gus says:

    Lalom, the HTWay program is designed so the balance code is separate from the control code. You can modify the control code, which is currently using the IRReceiver, with your own code to control the robot and leave the balance code alone. From your control code, you just need to adjust two variable to drive and steer the robot. If you want to make the robot track a line you may be able to do that but since the light sensor will need to be mounted in front, the sensor will go up and down while it is balancing. This may be a problem.

  14. Lalom says:

    Thanks Gus so, can I use the color sensor instate of light sensor to track the line? My problem is I’d downloaded the balance coed that has IRR code in it and deleted the Irr code but the robot can not balance. Would you please advise me ho to let it balance.
    My son need to go to challenge this 2 July I’m afriad that i’m running out of time so please advise asap.

  15. manu_xD says:


    I will build this robot soon, but i haven’t a I’R sensor. Does the robot also work without the IR Sensor?


  16. Gus says:

    Yes, you can make this work without the IR Receiver but you will need to make some changes to the program. Both the NXC and NXT-G versions have the control code separate from the balance code. All you need to do is alter the control code to tell the robot where to go and leave the balance code alone.

  17. [...] HTWay programs, both the NXT-G and the NXC versions, are designed so that the control code and the [...]

  18. Jay says:

    Dear HiTechnic,

    I’ve built your HTway robot minus the IR Receiver to test the balancing code with my HiTechnic Gyro. I’ve just downloaded the NXC program and the program is terminating unexpectedly stating “File Error!”. I get all the way through selecting the wheel size, laying the robot down and I get the countdown from 5 seconds with beeps. After that, the program terminates. Has there been any modifications recently that could be causing this or is something wrong with my NXT or BricxCC settings? I have firmware version 1.29 installed.



  19. Jay says:

    I disabled the IR control loop because I didn’t have one on my robot – and it works now! Thanks for such a great resource to building this self balancing robot! You guys rock.



  20. Gus says:

    Jay, the File Error was caused by the program assuming that the IR Receiver sensor was attached and attempting to read the data that did not exist.
    I see that you disabled the control loop, which is good. You can also keep the loop but replace the code that uses the IR Receiver with your own control code. Enjoy!

  21. DJ_Croft says:

    I would like the code for this robot for use with robotc. Can anyone help me?

  22. Alex Huynh says:

    Hi, as I understand, this use state feedback in order to stable the system, is that correct? What role does the motorControlDrive act in this? If I don’t want to drive the robot (i.e. make it move) and only try to balance it, do I need this term? And how do you choose the gain constant respectively? Is there a way to test/ calculate, or any initial point as reference? I’m trying to understand it in term of the math model and I’m still having a hard time to! Please help!!! Thank you so much.

  23. Alex Huynh says:

    Hello, what type of control is used in this segway? I read your code (in NXT 2.0 block diagrams) and it seems that the constants work like state feedback gain constant in state space control. Would you please explain why we have to divide the gyros angle and gyros speed by the wheel ratio and how do you calculate the wheel ratio? Also how do you calculate the gain constants for all the the terms in the code (i.e: constants for the gyro speed, gyro angle, motor speed, motor position, and the motor drive)? I am studying control system and I like your program a lot since it is one of the first codes use NXT 2.0 Labview based programming language and not the C code. I was able to follow your code but I am stuck at those things mentioned above. Please help! Thank you so much!!! AlexH

  24. n says:

    Do you guys have any ideas how made from this code a ballbot code? Thanks

  25. Gus says:

    A BallBot should work basically the same way except in two axis at the same time. You will need two Gyro sensors, one to monitor fall in forwards/backwards direction and one to monitor left/right direction. Program would then need to perform balance calculations in both directions simultaneously, one for each motor.

  26. Gus says:

    Alex – The wheel ratio numbers are based on the medium size NXT 1.0 tires and I have those defined as 1.0. The ratio numbers for the larger RCX (aka motorcycle wheels) and the smaller NXT 2.0 wheels is in proportion to that basic size.

    There are basically four factors and four constants used to maintain balance: Position, Speed, Angle, and Angular Velocity. Since the basic idea is that when these values are all taken into account, a certain amount of power is needed to maintain balance for a certain wheel size. When you have a bigger wheel, the amount of power needed is less since for a given amount of power, you will get a larger response with the larger wheel. The ratio in amount of power needed it is in fact dependant on all four terms but since the calculation for position and speed are also dependent on wheel size, their effect cancelled out. That is why only the angle and angular velocity terms need to take wheel size into account. Bascially, if you have a larger wheel, then the speed value is already under calculated since the speed is based axle degrees not actual distance covered over time.

    I hope this makes sense.

  27. Gus says:

    Alex, the motorControlDrive term basically moves the target location for where the robot tries to balance. Every time through the loop, the position value is adjusted by this amount times the time interval.

    When I developed this balance code I did a lot of experimenting and data logging analysis. I wrote a test program that would log all essential information for something like the last 5 seconds. Then when I would observe a certain behavior, which would usually result in a fall, I could analyze the data in Excel to see what terms would need to be adjusted to avoid the fall.

    I never created a complete mathematical model to determine the constants.

  28. n says:

    1. I have two gyros. I keep trying to make a ballbot code, but at first I must do working code for one motor (one way) – the same like your HTWay but with one motor. I’ve removed remote sterning code. But I don’t have idea how to remove right motor. I tried remove mrcRight and put instead to mrcSum = mrcLeft + mrcLeft but it didn’t work. Any Ideas guys.

    2. Maybe somebody have idea to how to do that segway but with PD PID motor control? I have done before segway with PID but this was with light sensor.. To do similar with gyro need to code to convert that when segway is plum then for example in = 0, when move left in = -x , right in = x.

    I dont’t know if is any option to solve second task, but I will grateful if somebody help me with first task.


  29. Alex St-L says:

    Hello, I want to modify/learn from the NXT-G file, and I have V1.1, Could you post the V1.1/V1.0 file for me please?
    PS: the reason i am not using the NXC code is because it is to complicated for me to use… :(

  30. n says:

    Are somebody have a NXC control code?

  31. n says:

    NXC bluetooth control code.

  32. Gus says:

    Alex, I’m sure that a 1.0 version can be made but it will lose some of the elegance of the 2.0 version. The reason is that the 1.0 software does not support floating point numbers (numbers with a fractional value) and only supports integers. This makes the math a bit messy since one has be sure that all the math operations don’t go so low that it loses too much precision. Right now I don’t have time to work on a 1.0 version but may try to make one when I have a little more time.

  33. Steve says:

    My son and I built this today on our NXT 2.0 platform. Everything worked well, even on his bed the carpet etc. Then all of a sudden the system won’t balance. It appers the PID loop is over correcting and running out of control then falls over. How should we debug this? We’ve been messing with the balance trying to understand the mechanics. What’s the system sensitive to mechanically speaking? What about the the gyro sensor? How could I test it?

  34. Gus says:

    Steve, My first thought is that you should double check the batteries. The program is fairly tolerant of a wide range of battery levels but if the batteries are too low then it will not be able to correct enough to balance. It may appear to overcorrect but most likely it is simply correcting too slowly and then tries desperately to regain balance.

  35. Steve says:

    Thanks Gus. Fresh batteries make all the difference in this application! Here’s a couple of battery data points for the community:
    Fresh batteries at 9.2 V :The system works fine, balances nicely and responds properly to IR commands.
    Previous not so fresh batteries at 7.9 V: erratically (4 inch moves) balances for about 20 seconds and then falls over. When given IR forward command promply falls over.

  36. Alex St-L says:

    Yah, about the batteries… i have NiCad type batteries and they are a bit heavy and when fresh they give me about 7.2 Volts… I also get the 20 second stand, then the over correction, then the faceplant (or backplant) what could I do to the program to fix this?

  37. Alex St-L says:


  38. Vladimir says:

    Hi! I have gyro sensor, but I don’t understand, how I can measure the angle, may be somebody tried it, can you help me?

  39. Vladimir says:

    And yet one, my Gyro Sensor give value -4<x<4 in rest, it's Ok? It's simple error?

  40. annathalia says:

    hi gus!

    i’ve been trying to comprehend ur program in NXT-G and i can say that i’m really doing a lousy job. i’m having a hard time in comprehending even the very first part of the program(the one concerning the ratio of the wheel) so may you please help me? i can’t understand why the nSelect number variable having the value of 2 is connected to a switch block..why does it have to be 2 and why does it have to be connected to the switch block having the ratios of the wheel? i hope this question will not annoy you or whatever. i’m just really fascinated by the task the robot performs so i really want to understand how it happens. thank you so much!!

  41. annathalia says:

    hi Gus!

    Do you have a tutorial class or something?? I want to enroll myself if there is any!!:D

    I’ve been trying to study ur program in NXT-G for 5 days now and I am doing a really lousy job. I’m having a hard time in comprehending the whole balance code, well actually I quite understand some, but apparently, understanding linear velocity is not enough to comprehend the whole code. May you please help me?? I just find it really wonderful to see a robot capable of balancing and I was moved to love lego because of HTWay. Please help me in understanding its program. Thank you Gus!

  42. Gus says:

    Hi annathalia,
    Sorry not tutorial classes. But studying others programs and experimenting with them is a great way to learn.

    The first part of the program for setting the wheel ratio implements the user interface to let the user use the NXT buttons to select the wheel size. The variable nSelect is the current selection and start of with this set to the second selection. The switch statement that is selected by the variable displays on the NXT screen the current selection. The inner loop in that MyBlock has a several Switch blocks based on the NXT buttons and these change the increment or if Enter button is pressed. The Switch at the end of the loop handles the wrap around so that the nSelect is always 1, 2, or 3.

    The HTWay is a tricky program to understand. It takes several things into account in order to balance. The four main variables, (the angular velocity, the angle, the position, and the speed), are all taken into account by that one monstrous linear equation. A lot of experimenting and data analysis went into selecting the constants to get the robot to balance.

    I think it is great that you study and try to understand this program but don’t be discouraged if you don’t fully understand it. Instead I suggest you try to modify the program to make the HTWay do your own things by changing the control loop at the bottom of the main program and leaving the balance code pretty much alone. In your own control code you can control how the robot drives by changing the variables controlDrive and controlSteer.


  43. Htway says:

    Hello, Gus
    I see that answers the concerns of people who ask is why I dare to write, I tried to make a program for the NXT 1.0, works like yours but I have no gyroscope, an accelerometer, but is that referred to in some sites can be done with trigonometric functions, I could give a direction, and angles to get the accelerometer´s Hitechnic, but how to maintain the accuracy of your program. thank you very much.

  44. Annathalia says:

    thank you for the response, Gus!

    oww..uhm Gus, i think i must master and familiarize myself with the different blocks in NXT-G first so i can fully understand that ‘monstrous’ balance code, right?? well, i believe it will take me million years or more before i can fully comprehend your program.:D

    so Gus, we just take into consideration the four main variables, (the angular velocity, the angle, the position, and the speed) because we’re trying to balance the robot, right? so what if i’m not trying to balance my robot, but i’m trying to make its motor respond according to the exact motion of the gyro sensor, i mean, i move the sensor clockwise with the angular velocity of 50 degrees/second and i want the motor to move forward covering the distance that the sensor covered in that that possible??if that is possible, then do i need the other variables??if not, then what are/is the variables/variable that i needed??sorry Gus if this is not related to your robot, but studying your program gave me the idea of this problem.thank you Gus in advance!!:D

    actually, i’m already working with the control loop. i’m trying to use another NXT controller with touch sensors as the remote control. Christian of Norway kind of inspire me for i noticed that he is just a kid like me, so hope i’ll be able to finish my code like him.:D

    thank you so much Gus! more powers to you and to good luck with your future inventions!: )

  45. Arsalan says:

    hi its an amazing project very welldone, i managed to balance the robot by using the .rxe file but while uploading nxt-g program it gives error and also when i run the nxc program after uploading via bricx my nxt brick software stucks n i hav to remove batteries n restart it every time n it stucks everytime i run nxccode any idea???
    Also plz tell me if i can control the HTway any other way than using lego pf remote coz i dont have it…thanx

  46. Stefan says:

    hi Gus,

    I’m trying to build my own balancing bot based on your code but i’m having trouble finding the right constants…
    You told Alex on december 15th that you did a lot of experimenting, logging and analyzing… I guess that rules out guessing those number and be lucky?

    Can you explain the process of finding those numbers a bit? What are the most important ones? Or are the equally important? Where do i start?
    BTW : I’m programming my robot in labview, but i guess finding those numbers has nothing to do with the programming language used?

  47. Gus says:

    You can’t completely guess the constants., It is possible to do the physics and derive the constants that way but there are inexact variables that way too, such as the exact amount of power you actually get from a motor so it is hard to imagine that it is possible to get it right without some experimenting.

    While working with this project I eventually got a pretty good feel for what role each constant did and I was able to identify, at least to some extent, what needed to be adjusted depending on the observed behavior.

    In your LV version you can also log data into a file that you then upload to the PC for analysis. That is what I did in my original debug NXC version. When I created the NXT-G version I pretty much implemented the exact same balance code. I actually have a LV version as well that I can email you if you would like. Again, exact same balance scheme, and constants.

    As far as most important, I would say it is the angle term, the one that is calculated by integrating the Gyro sensor value. This is the main term that keeps the robot upright. The other terms are primarily to compensate for momentum or to keep the robot in place. The most sensitive term may be the speed term as this value tends to be very low resolution. From one iteration to the next, the motors typically turn only a few degrees. The speed value difference between 2 degrees v. 4 degrees per iteration is huge. I have recently noticed that if I implement a low pass filter to average this term then I get improved performance.

    Good luck and let me know if you want my LV version of the HTWay.

  48. Gus says:

    I have notived that there are some issues with NXC if the optimization level is too high. If you lower the optimization level to 1 then it should compile and run correctly. If you want the NXC version to work without the IRReceiver then you need to remove the references to the IRReceiver so that the function to read the sensor is not called. This function causes an error if the sensor is not there.

    A version of the HTWay that can be controlled from a PC should be available soon.

  49. Stefan says:

    Thanks for the quick answer.
    I tried graphing the motor power to a labview chart, but that messes up the iteration time to much. Balancing with an usb cable connected to the robot didn’t help either. I will indeed need to find a way to write everything to a file and analyse afterwards…

    I would indeed like to see your labview version :-)

  50. Alfonso says:

    Is the controler used a propotional control?

Leave a Reply