The latest NXT-G block from HiTechnic is not a sensor block but a Motor block! This block implements a Proportional – Integral – Derivative, or PID, controller. Unlike the standard Motor block, which tends to emphasize relative movement, this block is designed to give absolute position control over the motor. The main input to the block is a Set Point value which is the angle position that you want to the motor to drive to. The block also supports several Reset actions to establish a reference position for the motor.
Why the HiTechnic Motor PID Block?
This block is an alternative to the standard LEGO Motor Block. Unlike the Motor block, which when used with a duration of degrees or rotations, gives you relative control over the position of the motor, the PID Block is designed to give you absolute position control. With the standard Motor block, you might use it to go forward 45 degrees, go another 45 degrees, then go backward 90 degrees. Each time the motor turns an amount that is relative to the position that the block starts in. With the PID Block you specify an absolute position. For example, if you want the motor to go to position 45, you can pass in that value to the Set Point input of the PID Block and it till drive the motor to that position. If the motor starts at position 100, then it will go backward to 45; if it starts at 0 then it will go forward.
This type of control makes sense when your motor has a limited range of motion. For example, if you are using the motor to control the position of a robotic arm, you will likely want to make the arm go to a certain position and then have it do something. Since you may not want to keep track of the current position, it is often easier if you can just specify the position to go to. That is what this block lets you do. If you use the standard Motor block, then the direction and duration needed to get to a certain position will depend on the current position.
Here are some possible uses for the Motor PID Block:
- Steering mechanism on a car (see IR RC Kart)
- Linkage control system to follow the input from a sensor (see the New program for the HiTechnic Ball Shooter)
- A selector mechanism for a sorter.
- A gripper mechanism that has multiple positions that you want to select between. Perhaps: Open, Closed, Crunch.
- A panning control mechanism where you want to accurately control the direction something is pointing.
How to use the block
The first thing you need to do is establish a reference position for the motors that you want to control. This is necessary because the NXT motors only have relative position encoders. When a program starts to run, you really can’t be certain what the start positions are for the motors. To establish this reference position, the PID Block supports several reset actions:
- Reset at Current Position – use this if you know the current motor position and you want to assign this a particular Set Point value.
- Reset at Forward Limit – use this to drive the motor forward until it reaches the mechanical limit, assign this position the Set Point value.
- Reset at Backward Limit – use this to drive the motor backward until it reaches the mechanical limit, assign this position the Set Point value.
- Reset at Mid-point of Limits – use this to drive the motor first to the forward limit, then then to the backward limit, calculate the mid-point, and then set the Set Point to this mid-point location.
Once the reset action has set the Set Point based on the desired reference position, all subsequent uses of the PID Block to Power Toward Set Point will be relative to this reference position.
For example, in the IR RC Kart, the reset action is Reset at Mid-point of Limits. When this block is run, the steering motor first runs forward to find the steer-right mechanical limit and then it runs backward to find the steer-left mechanical limit. The block then calculates the mid-point position between the limits and assigns this position to the passed in Set Point value, in this case 0. The program looks like this:
Note that when you set the PID Block to one of the reset actions it automatically lower the power to 25. Generally when you use the block to find a mechanical limit you do not need much power. For the IR RC Kart, however, the steering motor has to have enough power to tilt the robot so it uses 75 power to find the limits. You can choose any power level from 0 to 100 with the reset action though the power should be sufficient to guarantee that the motor does make it to the limit but not so high that it does damage to the robot. On the IR RC Kart, the steering mechanism is very strong and can easily handle the 75 power force at the limit.
The block find the mechanical limit by running te motor at the specified power and monitoring the progress of the encoder. It has found the limit if no progress is made in a 1/10 of a second.
In the demonstration video you will also see the Reset at Current Position option used when the reference position can be determined with a Touch sensor. In this case the touch sensor has been set up so that it will get pressed and released at one particular position of the motor. Here is the beginning of that program:
Here you see that first the standard Motor block is used to get the motor started. It has been set to use a power of 30 and a duration of unlimited. The Wait block has been set to wait until the touch sensor is bumped, in other words both pressed and released. That way the program can be started with any possible position, even starting with the touch sensor pressed. The motor will run forward until the touch sensor goes from pressed to released and then the PID Block will reset to this position and it is assigned the Set Point value of 130.
Using the block to drive to a position
Once the reference position has been establish, you can now use the PID Block to control the motor to go to a certain position. There are two different ways to using the block:
- stand-alone: – If you set the Wait for Completion option, then the block will only go to the next block in the program once the motor has
reached the destination Set Point. This is good when you have a certain position that you want the motor to get to before you do anything else.
- in a loop – If you need to have a Set Point that changes over time, then you will want to use the block in a loop and have the Wait for Completion option cleared. In this case the block will just update the power of the motor to get it to drive toward the Set Point.
To use the block in stand-alone mode, the Action should be set to Power Toward Set Point and the Wait for Completion option should be checked. The position that you want the motor to go to should either be set in the configuration panel Set Point field or passed in with a data wire. When you use the block in this way, the motor power will be controlled to get the motor to reach the desired Set Point. When the block is done, the motor will stopped and at the desired Set Point location.
Here is an example of the block used in a stand alone way:
The selected block in this program has been set to drive the NXT motor to position -45 degrees. Note that Max Power has been set to 80, which indicates the PID controller can use a maximum power of 80 to get to the Set Point, and that Wait for Completion is checked.
In a loop
If you want the sensor to follow some moving Set Point, for example the Accumulated Angle from the Angle sensor, then you will want to use the PID Block in a loop with the Wait for Completion option cleared. Inside the loop you should pass in the desired Set Point value with a data wire to the PID Block. In this case, the PID Block will just update the power to the motor to make it drive toward the Set Point. The block will automatically adjust based on how quickly it is called though you will not want this loop to be too slow. If you put a large delay or do something that significantly slows down the loop, then the performance of the PID controller will be adversely affected.
Here is an example of the PID Block this way together with the Angle Sensor:
In the program the Angle Sensor is first Reset in the begeinning outside the loop. This ensures that the first Accumulated Angle values from the block in the loop will be zero. This Accumulated Angle value is then passed into the the Set Point input of the PID Block. Note that the PID Block is set with the Wait for Completion cleared. That means that everytime through the loop the power to the block is just updated to drive the motor toward the block. Just like in stand-alone mode, the block will still regulate the power using the PID controller so that the motor will have minimal overshoot.
If you have multiple motors, you can use multiple PID Blocks in the loop one after the other. Since the block automatically adjusts for loop time, it will work even if you are controlling all three motors in the loop. You can also have parallel loops in your program and the PID Block will also work. In technical speak, the blocks are said to be thread-safe and reentrant. The only exception to this is the Reset actions, these should not be done in parallel tasks.
About the PID Controller
A PID Controller is a commonly used mechanism for controlling a system where there is some system variable that you want to get to specified Set Point by manipulating one or more inputs. In this case, a PID controller is used to control the power of a NXT motor to make the output axle position of the motor drive toward a specified Set Point position. Basically what a PID controller does is that it first calculates the error between the current position and the Set Point and then it calculates a power value to be used based on tis error, the change in error, and the integral, accumulated sum, of error. Each of these three terms are multiplied by respective constants and then added together to get a power value. The idea is that the further from the Set Point that the motor is, the more power it will use to get to the Set Point, that is the proportional part. The derivative is the change in error, it tries to avoid overshooting the Set Point by reducing, or even negating, the power as it approaches the Set Point. The Integral part takes care of the situation where the motor comes out short and is close but not exactly at the Set Point. In this situation both the proportion and the derivative terms are low but with time the integral term will wind up enough to provide sufficient power to finish getting to the Set Point.
The form of the PID controller that is implemented by this block is known as standard form. If you click on the Show button on th configuration panel, then you will see the formula and get the chance to modify the constants.
With this form of the PID controller formula, the proportion term is factored out of the equation. This results in semi-understandable units for the three constants. The Proportion constant is simply power per degree of error. In other words, for every degree of error, use this much power. For both the integral and derivative constants, the units are in milliseconds. Since change in error is measured in degrees per second, if you multiply that with a constant in time units (milliseconds), you get a value in degrees. For the integral term, the sum of the error is integrated over time so the units are at first degree seconds. When that is divided by a constant with units in milliseconds, then the result is also a value in degrees. Since we now have three values all in degrees, we can add them together and then multiply by the proportion constant which will result in a power value.
The PID controller is actually a bit more complicated then just the formula used to calculate the power. For example, before power is applied to the motor it is restricted to the range of 0 to Max Power, another one of the inputs to the block. The integral term also has some special processing to avoid a phenomena known as integral-windup. Basically an unintended consequence where the integral term works against the proportion term to prevent the motor from quickly getting to the Set Point.
If you want to learn more about PID controllers then the Wikipedia article PID controller.
Please give this block a try and let us know what you think. If you find some good uses for the block let us know, we would love to hear about it.