AME 30315 Pendulum Project

From Bill Goodwine's Wiki
Jump to: navigation, search

Administrative Things

  • Hopefully you already know your group assignment.
  • John Gallagher, who is serving as a TA for this project, will be in 212 Stinson-Remick on Thursday evenings from 8:00-10:00pm. His email is jgallag8@nd.edu.
  • You may reserve one of the pendulum platforms using the paper sign-up sheets near the pendulums in 212 S-R. Your group may only have one pending reservation at any given time. In other words, your group can only make one reservation and only after that reservation time is over may you make another reservation.
  • The project is due at 5:00pm on the last day of classes. There will be no extensions. If all the pendulum platforms are reserved the evening before it is due, that will not be accepted as a valid excuse for not completing the project. You will HAVE to work ahead of time and in an organized manner because it will basically be impossible to start this a couple days before, even with unlimited access to one of the platforms, and finish.
  • It is expected that greater than 80% of the time spent on this project will be spent working together with all the group members present in the same room at the same time on the same thing. If this is not happening, you must let me know. If you have a delinquent group member, you must let me know. Also you must let me know these things when it is happening, not when the project is due.

Introduction

In this project you will design a feedback controller to stabilize an inverted pendulum. The basic steps are:

  1. system identification,
  2. controller design,
  3. implementation and verification.

The first and third steps require that you be able to program a microcontroller. All three steps, but particularly the second step, requires that you understand the course material.

This web page provides a description of the system and instructions to download a program. Read everything before the "Getting Started" section, but do not worry if you do not understand it all. You will probably have to re-read it several times.

The System

The pendulum and controller are shown in the picture below. It is comprised of

  1. the pendulum,
  2. a d.c. motor with optical encoder,
  3. an H-bridge current controller,
  4. a Freescale 68hc11 8-bit microcontroller with peripherals, and
  5. a usb-port logic analyzer.

The microcontroller is very inexpensive and has limited capability, as is realistic in industry where component costs are of significant importance.

Pendulum system.

The following elements are illustrated in the picture.

  • The smaller green printed circuit board, on the lower left, with the serial port on it, has the 68hc11 microprocessor on it. This will be called the "hc11 board" or "microcontroller board." The actual hc11 is the square chip on the vertical board sticking out from the base. The chip on the base board is the serial interface. The round silver component next to the hc11 is the clock. The larger rectangular chip on the other side of the vertical board from the hc11 is the EEPROM. On the extreme left barely in the picture, you can see the very end of the white serial cable that is plugged into the hc11 board.
  • The larger printed circuit board, on the upper left, provides the interface between the microcontroller and the H-bridge, the encoder, the index encoder and some limit sensors. It is attached to the hc11 board with a grey ribbon cable. It will be called the "interface board." It also has a chip on it that is a decoder for the encoder. Whenever the encoder encounters an edge, the decoder generates a pulse that produces an interrupt on the hc11. The interrupt service routine for that interrupt queries the decoder to determine which direction the pendulum is moving and then increments or decrements a counter to keep track of the number of encoder ticks that have occurred.
  • The H-Bridge is in the center of the picture and has the heat sinks on it. It takes the PWM signal from the hc11 and produces a current proportional to the duty cycle.
  • The motor is on the right in the picture.
  • On the right edge of the interface board, you can see three colored wires going to the upper edge of the picture. These wires are connected to a USBee SX logical analyzer, which can be connected to the USB port on a PC. If you run the USBee tools on the PC, you can see when interrupts are occurring, etc.

You will need to use one of the desktop computers in 212 or 213 Stinson-Remick. Those computers should have the following software installed:

  • the 68hc11 port of the gcc compiler,
  • putty, to be able to communicate with the microcontroller over the serial port,
  • notepadd++, for editing your programs, and
  • the logic analyzer software.

There are 10 pendulum platforms and five USB logic analyzers on the window sill in 212. Return them when you are finished. I have been told there are many more logic analyzers available in S-R. If there are any platforms available, you may use it. However, if another group has it reserved, you must relinquish it to them.

All the software can be found in the start menu, except the compiler. To run that you need to open a command prompt (under Accessories) and type "m6811-elf-gcc". If it responds with "no input files" then it's installed. If it responds with "no recognized as an internal or external command" then it's not installed or is not in your path.

Interrupts

There are two interrupts in the program. One is an output compare interrupt and the other is a pulse accumulator interrupt.

  • The code that is provided has the output compare interrupt running at 880 Hz and is for the pulse width modulation control of the motor. It is output compare 3, OC3. If the motor power is on, you can hear this one in operation because you can hear an 880 Hz sound from the H-bridge.
  • The pulse accumulator interrupt happens whenever the optical encoder senses an edge. There is a decoder chip on the board that the hc11 can query to determine which direction the pendulum is moving. On the interface board, there is a green LED that will be on when the pendulum is moving to the right and off when it is moving to the left. It has RIGHT printed next to it. The red LED next to it that has LEFT printed next to it does not come on when it is moving to the left. It is on when the pendulum is at either limit position. I believe right and left refer to the direction of movement when the pendulum is inverted.
  • The encoder also has an index channel, which senses when the encoder passes through the nominal zero position. However, because it was assembled by hand and also because the motor shaft may slip in the collar on the pendulum, the index will never exactly be at 0 degrees. Part of the calibration process will be to determine the offset between the index and the real zero position. The index channel on the encoder does not generate an interrupt. However, it does make the white/blue LED flash that is next to the grey ribbon cable on the interface board and can be sensed by the hc11 because it is connected to a pin on PORTA. It can also be sensed if the program in the microcontroller happens to be looking for it at the time it is triggered by checking the status of the pin on PORTA to which it is connected.

Important Parameters

  • There are approximately 5 or 6 interrupts per angular degree of motion of the pendulum. More specifically, there is 0.18 degree per interrupt generated by the encoder.
  • There is an index on the encoder that happens only once per revolution. It should be aligned so that the pendulum is near vertical when the motor goes through this position. There is a whitish/blue LED near the grey ribbon cable that flashes when it goes through this position. The calibration steps outlined below provide for an offset if this is not aligned with the vertical position. However, it must be the case that this position is within the range of motion of the pendulum. If the shaft slips too much and it's outside the range of motion, then the code will not work.
  • All the I/O for the pendulum control is through PORT A on the hc11.
    • pin 0 is connected to the limit sensors for the hard stops.
    • pin 1 is connected to the decoder in a manner so that it is high when the encoder is moving in one direction and off when it is moving in the other the direction.
    • pin 2 is connected to the encoder index (close to the top).
    • pin 3 is not used.
    • pin 4 has been used for various debugging things. It is ok to leave it unused. If you need to debug something that is happening very fast, you may want to have your program toggle it, and you can use the logic analyzer to see the timing of how it is triggered.
    • pin 5 is the PWM.
    • pin 6 is connected to the red LED on the hc11 board. The code that is supplied is written so it is toggled at 20Hz.
    • pin 7 is connected to the decoder which pulses whenever the decoder receives an edge from the encoder.

You will need this PIN diagram in order to know where to connect the logic analyzer.

Switches

  • On the hc11 board there are two sliding switches and one push button. The switches are on the vertical board on which the actual hc11 processor is mounted. The push button is on the base board and is visible in the picture next to the red LED that is next to the serial port. The sliding switches are shown in the picture, and in fact, are right in front, but they are hard to see. The are facing the front of the picture on the vertical portion of the hc11 board. If you consider the "front" of the pendulum to be the side with the pendulum then the picture was taken from behind and the sliding switches and push button are on the back. The switches must be together to download a program and apart to run. The button near the switches is the reset button and must be pushed right after any time the switches are moved. It will also start your program over if it is currently running. Be careful moving the sliding switches because the vertical hc11 board can be pulled out of its socket fairly easily. If it comes out, just put it back in. Be sure that the switches are facing the back because it may be possible to put it in backwards.
  • The four white buttons on the interface board are wired to PORT B on the processor. You do not have to use these, but they can be accessed by your program. You may want to use them, for example, to change a gain value without having to recompile and download your program. It is acceptable to leave these as unused for this project. The rightmost button is wired to the reset button on the hc11 board and does exactly the same thing.

Getting Started

This section outlines the steps to write, compile, download and execute a program on the microcontroller. Until you have a controller designed that is supposed to stabilize the pendulum, make sure the pendulum is pointing down.

The file format that can be downloaded to the hc11 is called an "S-record" and has a filename that has a ".s19" suffex. Here is an example of an S-record that commands a square-wave torque to the pendulum with a period of approximately ten seconds. It is a text file, so it is something you can look at and open in an editor, but it is not really decipherable. Save this program on your computer.

The steps required to download the run this example square-wave program are as follows.

  1. Save the S-record in the link above to your computer. Also save the files msload9.bin and pms91.bat in the same directory as the S-record.
  2. Ensure that the pendulum is hanging down.
  3. Plug in the power plug for the microcontroller board, but NOT the motor (the smaller plug is for the boards and the larger is for the H-bridge and motor). Some LEDs light up on the board when you plug in the right one.
  4. Connect the serial cable to the serial port on the computer and make sure it's connected to the serial port on the hc11 board.
  5. Set the two switches on the hc11 board to be "together" that is the top one should be down and the bottom one should be up. Push the reset button. This puts the board in "bootstrap mode" to download the program to the EEPROM.
  6. Type
pms91 StudentCode
The pms91.bat file is a batch file that copies stuff to the serial port. First it sends msload9.bin to the hc11, and with this program, the hc11 knows to copy the other stuff sent to it into the EEPROM.
  • The program needs access to the COM port. If another program is using it, it will be blocked. The first time you do this, it probably won't be a problem, but you definitely will be debugging stuff via the serial port later. If you leave putty running, it will block it, in which case you will get a warning saying basically that.
  • If it's working, you will see a message like:
                     TECHNOLOGICAL ARTS
         S-record File Downloader for 9MHz MicroStamp11
         ==============================================
For expanded-mode 68HC11Dx systems with external EEPROM/RAM
.
NOTE:   For proper operation, do not apply or remove board power
        while it is Write-Enabled
.
USAGE:  to download a file called myfile.s19 via COM1, type
                   pms91 myfile
.
1)  Make sure Docking Module is connected to COM1
2)  Make sure MicroStamp11 is properly inserted in Docking Module
3)  Apply power to Docking Module (+5VDC to +12VDC is acceptable)
4)  Place both switches in LOAD position
5)  Press target board RESET button.
.
Press C to abort, or...
Press any key to continue . . .
        Installing bootloader in RAM now...
        (to abort, disconnect serial cable)

Status for device COM1:
-----------------------
    Baud:            9600
    Parity:          None
    Data Bits:       8
    Stop Bits:       1
    Timeout:         OFF
    XON/XOFF:        OFF
    CTS handshaking: OFF
    DSR handshaking: OFF
    DSR sensitivity: OFF
    DTR circuit:     ON
    RTS circuit:     ON

        1 file(s) copied.
Programming EEPROM now... (takes approximately 20 sec/Kbyte)

Status for device COM1:
-----------------------
    Baud:            1200
    Parity:          None
    Data Bits:       8
    Stop Bits:       1
    Timeout:         OFF
    XON/XOFF:        OFF
    CTS handshaking: OFF
    DSR handshaking: OFF
    DSR sensitivity: OFF
    DTR circuit:     ON
    RTS circuit:     ON

        1 file(s) copied.
EEPROM programming complete.
WRITE PROTECT MicroStamp11.
Place MicroStamp11 in RUN mode.
Press RESET button.
   Your program is now running...

Be patient. This can take a minute or two. It's not done until you see the "programming complete" line. Move the two switches into the opposite positions (top one up and bottom one down), or in other words, push them apart. When you push the reset button, your program will run!

Things may be a little underwhelming at this point because it may seem like nothing is happening. To make things happen you have to establish communication with the hc11. To do this, start putty. In the opening window, click on "serial" for the connection type, and then click ok. If you click the reset button again, you should see a welcome message and instructions to move the pendulum through the zero position. If you move it all the way left and right, you should see an indication that it found the zero position. If you plug in the motor, you should hear the PWM and also see the pendulum alternate between a left and right position with a period of a couple seconds.

The program StudentCode.s19 basically commands a square-wave torque to the pendulum with a period of several two seconds. So it should move one way and oscillate some, then after several second or so, move the other way and oscillate some, etc.

When you are done, CLOSE putty! If you forget, it will block you the next time you try do download an S-record.

Compiling and Downloading a Program

Ultimately your job is to edit the program to implement a controller that you design. In this section you will compile the source code to make an S-record that does ths same thing as above. You need to download and save the following files in the same directory

What each of these files do will be described later. In this section the point is to just successfully compile them. You must have them all in the same director or it won't work.

To compile the program and create the S-record type

m6811-elf-gcc -Wall -N -mshort -Wl,-m,m68hc11elfb -msoft-reg-count=0 -o filename.elf filename.c

You need to replace "filename.c" with whatever program you are compiling. It will create a file called "filename.elf". You should probably replace "filename.elf" with the same prefix as your C program, i.e., StudentCode.elf. An elf file is a file in Executable and Linkable Format.

To translate the elf into an S-record, type

m6811-elf-objcopy --output-target=srec filename.elf filename.s19

Again, replace "filename" with whatever. The file "filename.s19" is the S-record that you can download to the hc11 as outlined above. You may want to use a different name for the S-record so you can be sure that when you use it, it doesn't happen to be the same one that you downloaded before.

Do these steps for StudentCode.c to make sure you can compile, make the S-record and download it to the hc11.

If want to install the compiler on your own computer, do the following:

  • To add that program to the PATH, just add " ;C:\usr\bin ", assuming that the program is installed in C:\usr, which should be the default. If you want to check that it works, you can type "m6811-elf-gcc" in the command prompt while in some other directory, and if it recognizes the command you should get a message that says something like "no input files."
  • Notepad++ and Putty are pretty easy to find, and other programs can be used just as well.

You do not have to install the compiler on your own computer, but it may be convenient if and when the lab gets crowded.

Notes on Editing the Program to Control the Pendulum

Do NOT edit either vectors.c or memory.x. The former defines the interrupt vector so that when an interrupt occurs, the processor knows where to go to handle it. The second is the memory map for the processor. You can certainly look at each one. I don't think it would hurt or corrupt you.

The file serial.c provides functions to communicate stuff through the serial port. In particular, for your purposes, it provides ways to print out information that may be useful for you to debug your program. Note: serial communication is very slow. If you try to print too much stuff, it will slow down your program and affect its performance. As will be described later, the main control loop operates at about 20Hz. The code seems to be able to handle printing up to the order of 30 characters in that loop. If you try much more, it may take longer than 0.05 seconds.

You can figure out all the wonders of serial.c by reading the comments in it. The two main functions you will use are:

  • outstring() which can print a sring to to the serial port and
  • out_unsigned_dec() which can print a number.

If you want to print positive or negative numbers, you have to go through the labor of checking whether it is positive or negative and printing the "-" sign manually!

The file StudentCode.c has most of the functionality you need to control the pendulum. You should be able to complete the project by only modifying the main() function in StudentCode.c. However, in order to be able to do that, you may have to figure out how many of the other functions in the file work.

  • It has an 880Hz PWM written already. That is the OC3 interrupt and the interrupt handler is the first function after main().
  • The second function after main is the interrupt handler for the pulse accumulator (the encoder).
  • The next function is the default interrupt handler, which will catch if any other interrupts happen (which should not happen).
  • The function init_interrupts() configures the hc11 so that only the interrupts we need are enabled. No interrupts will happen if you don't initialize the processor properly with code that is in this function.
  • As you might guess, the function set_torque() is a useful one. It takes one argument, a long integer. This must be a long integer in order to be able to do the calculations with sufficient precision. However, ultimately the largest magnitude you ever want to send to set_torque() is 400. In other words, do not send anything greater than 400 or less than -400 or else the PWM (at least as we've supplied it) will not behave as you expect. I think that if you send it, for example, 600, it will NOT just max out at 400, but actually overflow and do unexpected things. Once you start programming torques, you should probably always have a check before set_torque() that makes sure the computed value is between -400 and 400, and if it's out of that range, just set it to -400 or +400, whichever is appropriate.
  • On the hc11, the int type and short type are the same length, 16 bits. A long is 32 bits. The processor only does integer arithmetic, so in order to have relatively precise calculations, you will have to scale things to larger values. For example, if you need to compute 3.45*u, you probably will need to compute 345*u and know the answer is 100 times too large. You must be careful and consistent with this because, obviously, you don't want to add one thing that's been scaled by 100 with another that has not been scaled or been scaled by a different amount.
  • The function check_encoder_direction() checks if the pendulum is moving clockwise or counter-clockwise.
  • check_encoder_top() checks the pin on PORTA that the index channel is connected to and returns a 1 if the pendulum is at the index position. This should be somewhat close to the top (within 20 degrees seems typical).
  • pause() pauses for a while. It takes an unsigned int, so the maximum it can delay is however long it takes to count from 0 to 65535. Counting up to that seems to take about a second.
  • The function init_ports() enables all the necessary pins that are used on PORTA of the processor that communicate with the PWM (pin 5), encoder (pin 7) and direction (pin 1).
  • The function set_zero() is called near the beginning of StudentCode.c. When the program starts running, the controller has no idea what position the pendulum is in. This function instructs the user to move the pendulum through the zero position by hand (just move it from one end to the other somewhat slowly). When it detects the index, it sets the value of the position to zero.
  • welcome() should be obvious.
  • __premain() DO NOT EDIT THIS. Some stuff actually has to be done within the first few clock cycles, and that stuff probably isn't related to what you need to do.

There is not a function that gives you the pendulum position. The variable pos does this and is incremented by the pulse accumulator interrupt. The value of pos at any time is the position of the pendulum in encoder ticks. If you have a variable that is equal to pos*18, it will be the position of the pendulum in degrees times 100 relative to the index position.

Be very careful writing your code. The compiler option '-Wall' tells the compiler to give all possible warnings. In the development of this project it became VERY obvious that strict C code must be written. If it gives you a warning, fix it. Just because it compiles and even runs, doesn't mean it's doing what you expect. Things like 'a=b' where a is a long and b is an int generates a warning, as it should, and fixing all of this in your code is necessary.

Initial Steps

I would suggest breaking it down in the following steps before you try to implement the real controller.

  1. First modify the StudentCode.c program so that it pauses for a longer or shorter time between switching the torque. Also perhaps increase or decrease the torque.
  2. Write your own calibration code that sets an offset variable that makes the zero angle not equal to the index, but rather equal to the real zero, which corresponds to when the pendulum is hanging straight down. You can do this by writing 'pos to the serial port and just checking the value when it hangs straight down. The negative of that will be the offset. Each platform will have a different offset and over time it may even change for individual platforms.
  3. Implement proportional control. This will not give satisfactory performance, but is a good first step.

System Identification

To determine the transfer function describing the response of the system, do the following.

  1. Enable logging in putty so that everything that gets printed to the screen gets saved.
  2. With the pendulum hanging down, command a step input for the torque.
  3. In the while(1) loop in main() there is an if() statement that checks if it's time for the 20Hz control loop to execute. Inside that if() statement, get the position and print it to the serial port. You may also want to create a variable that is 100*time, that increments by 5 each time that if() is true. If you print that right before the position, what gets printed on the putty terminal should be the time and position every time the control loop executes.
  4. After it settles down, quit putty. Edit the log file to cut out any extra junk and you should have two columns of numbers, where one is time and the other is position.
  5. Plot it in matlab and, hopefully, do that problem correctly to find the natural frequency, damping ratio and scale factor in the numerator.
  6. Good engineering practice, obviously, requires you to verify stuff you determine by repeating the experiment several times and checking that what you computed for the first one gives a good match for the others. This should be true for different directions as well as different magnitudes of inputs.
  7. Your report should contain a graph of the step response you used to compute the system parameters as well as enough comparisons with other responses to give confidence that your numbers are good.

Implementing a Controller

In our class, we will only consider continuous-time systems. However, the microcontroller only works in discrete time steps. Hence, you must convert your controller from continuous-time to discrete-time. In the frequency domain, continuous-time systems are represented by the Laplace transform, with s as the independent variable. In the frequency domain, multiplication by s represents differentiation, i.e.,

\mathcal L \left\{ \dot x(t) \right\} = s X(s).

In discrete-time, the analogous transformation to the Laplace transform is called the z-Transform, with, not surprisingly, the independent variable being z instead of s. In discrete time instead of a function depending continuously on time, a function is only defined for a sequence of times, i.e., instead of x(t) we have x(T), x(2T), x(3T), etc., where T is some time step. In discrete time, under the z-transform, the analog to multiplication by s being differentiation is that multiplication by z is a time shift. Specifically, z X(nT) = X((n+1)T), it shifts the function ahead by one time step. Dividing by z shifts it back. Multiplication by z twice shifts it ahead by two time steps, etc.

The approach we will take in this class, which is relatively common, is to do all of our work in the continuous frequency domain and at the very end convert our continuous controller to a discrete-time one. For very simple operations you would naturally do this, for example, replacing the derivative of a function, f'(t), by [f((n+1)t)-f(nT)]/T. However, for more complicated things, this could get confusing. It turns out that the usual trapezoidal rule for integration gives a nice relationship between s and z given by

s = \frac{2}{T} \frac{1-z^{-1}}{1+z^{-1}}.

This is called Tustin's method. Now, say you have some controller that you designed given by, for example

C(s) = \frac{F(s)}{E(s)}=\frac{s+2}{s+15}

where F(s) is a control force and E(s) is the error signal. What you do is substitute the equation relating s and z into C(s) to get it in terms of z, e.g., for this problem (if I did the algebra correctly...)

\frac{F(z)}{E(z)} = \frac{2(1+T)z + 2(T-1)}{(2 + 15T)z + (15T-2)}

for the right hand side. Because this is the z-transform for the error to the force, we have

(2 + 15T)z F(z) + (15T-2)F(z) = 2(1+T)zE(z) + 2(T-1)E(z).

Because multiplication by z is a shift forward in time, in discrete-time this corresponds to

f((n+1)T) = \frac{2(1+T) e((n+1)T) + 2(T-1)e(nT) - (15T-2)f(nT)}{2+15T}

which is our computation for f(t) at the new time step. It depends on both f and e at the previous time step as well as e at the current time step (t=(n+1)T). For a lead-lag compensator, the numerator and denominator will both be second-order in z, so the computation for the new control input will depend on the current error as well as the error and control at the previous two time steps.

You should definitely do the computation by hand. You should know too that Matlab has a function called c2d() which stands for "continuous-to-discrete" which does this conversion computation. You need to give it the time step as well as the method. For this example with a time step of 1/20 and using Tustin's method,

>> c2d(tf([1 2],[1 15]),1/20,'tustin')
 
Transfer function:
0.7636 z - 0.6909
-----------------
   z - 0.4545
 
Sampling time: 0.05
>> 

Assuming this is correct, let's proceed to implement it on the hc11. That processor is CHEAP ($3.50), so it's not going to be able to do too much math. In fact, floating point arithmetic requires an additional library is is way too slow. It can, however, very quickly do fixed point (integer) arithmetic. Assuming the matlab controller for the pendulum (it won't work, by the way, this is just an example...) with u representing the pwm level and err the error, we would be tempted to write

u = 0.4545*u_old + 0.7636*err - 0.6909*err_old;

where u_old and err_old were copied from u and err at the bottom of the 20 Hz loop. But it can't do the 0.4545*u_old computation. What it CAN do is

u = 4545*u_old + 7636*err - 6909*err_old;
u = u/10000;

This will allow it to retain necessary precision but still do the computations in fixed-point.

Hints:

  • For the hc11 an integer is 16 bits, which has a maximum value approximately 64,000 (half that if it is signed). When I implemented the controller, the computation for u in the first line (before it was divided by 10000) exceeded 32k. Hence, the variable type for u in the code had to be a long integer. This made u 32 bits, which was large enough for the computations (but slower).
  • You must be very careful with the variable types in the code. Embedded systems are very pick about them and passing an int to a function that wants an unsigned long, for example, may compile but exhibit flaky behavior because the function isn't getting the intedned value from the variable.
  • Also, be careful printing stuff to the serial port. It can only put out so much stuff. One mistake I made was to compute some stuff, print it, use it in another computation, print that, and then set the torque to the computed value. It turns out that even though the loop was still running at 20Hz, there was enough delay in the printing that it didn't work too well. I would suggest that if you print stuff, do so judiciously and also to do all the computations and torque_set commands at the top, and then print out debugging things. If the printing slows it down to less than 20Hz, it won't complain or otherwise indicate anything, but effectively the time step will be longer than what you used in your computations, and things won't work!
  • Be very careful with units. You will definitely save time if you are careful with all the units whenever you write something. Are you using encoder counts for the position, or degrees, or degreesx100? I would have saved a few hours if I were more disciplined about this.
  • I think a positive PWM signal creates a negative angle. Watch the signs for this! This too cost me a few hours.

Project and Report Content

You must write this report as if I were your boss and people trusted their lives to the product we were developing (medical device, airplane, etc.). What I am looking for in this project are the following:

  1. A controller design that works. It should stabilize the pendulum for any desired angle between +/- 30 degrees of vertical.
  2. The report should contain representative step responses, for example having it stabilized at zero until 10 seconds, then stabilizing it at 20 degrees. If it seems to work perfectly for all angles in that range, then say so and give representative responses. If it has any sort of steady-state error, then you should report it. I do NOT want voluminous data unless it's necessary. For example, if the error at zero is zero, at +/- 10 degrees is 1 degree, at +/- 20 degrees is 3 degrees and at +/- 30 degrees is 5 degrees, then just say that and report what the trend seems to be. If it's not so simple, then a table giving error as a function of, say, 5 degree increments would be good. A good report will effectively communicate the nature of the error in a concise way. (Putting data in an appendix is ok, but your boss won't read that; a colleague following-up on your work might find it useful). Having one or two plots showing it works for zero and one other angle with nothing more is not an acceptably professional report. It is not acceptable here, and not acceptable in the real world. Imagine showing your boss at Boeing that the aileron actually deflects 10 degrees when that's what you want it to do. He or she will likely actually care about some other angles too. In other words, you must thoroughly evaluate the performance of your design.
  3. You must also justify any decisions you make. For example, in the system identification section above, you determined the transfer function for the pendulum when it's hanging down. You must show in your report how you determined the transfer function for the inverted pendulum from that. If I'm your boss and people's lives depend on it, I'm not going to accept something like "when the pendulum is hanging down, we determined zeta and omega_n to be xxxxxxx. Thus when it's inverted the transfer function is yyyyyyy." There are multiple steps to this. For the downward-hanging pendulum, just showing a plot of a step response and saying the damping ratio and natural frequency are such-and-such is not sufficient. You must compare the step theoretical step response with the parameters you determined with the actual response. You must also do it for step inputs of different magnitudes and signs than the one you used for your computations. You should show such comparisons on the same plot (having two plots, with different units but arguably qualitatively similar responses is not sufficient). If the units you use are the PWM signal level and encoder counts (what I used), then on a plot of a step response of the real system, I should see the theoretical response with the same units compared with it. For going from downward to upward, you need to do some analysis (mechanics). This is important, because it will give the transfer function that you will use to design your controller. If I'm responsible for people's lives, I want to know you did each step correctly.
  4. After you have a good model, you must implement a lead-lag controller that gives satisfactory transient and steady-state performance. I'll leave it to you to decide what good performance is, but you must predict the performance (overshoot, settling time, etc) based on theory and correlate it with the actual system response. E.g., "for the system we designed, the theoretical step response for an input of 10 degrees is illustrated in Figure YYZ, which also shows the actual response of the system." The design of your controller must be supported by analysis, specifically root locus plots and other analyses. You must predict the transient and steady-state performance and compare the actual performance to that. You must include in your report root locus plots for the transfer function and the means by which you used them to design the controller.
  5. Since you did your analysis in continuous time, you must include in your report the details of the computations to convert it to discrete time.
  6. Your report must contain a comparison of the predicted response of the system versus how it actually responds. You must show this for stabilizing to the zero position (the real zero position, straight up, with the appropriate offset determined) as well as stabilizing to several other positions, say 20 degrees, -30 degrees, etc. Any significant differences between the predicted and actual responses must be explained.
  7. Your report must contain a link to a movie showing the system in action.
  8. Your report must show any warnings that the compiling command gives. In other words, cut and paste from the terminal whatever is printed out when 'm68hc11-elf-gcc' is run. It must contain the '-Wall' option. The only allowable warning is the one that it says about the eeprom memory definition.
  9. Your report must contain your code. You do not need to include vectors.c, memory.x and any other files you used but that were unmodified from what was supplied.
  10. Every group must validate their design and determine the best controller/gain combination. However, in your report you must include computations for the discrete controller based on the parameters in the following table. This of the assigned values in the following table as "homework" in that each group must show they can do all the necessary computations for the indicated parameter values. You may use those as a logical starting point, but it's not necessary. You should validate the assigned values in matlab. It is not required to actually implement the controller in the real pendulum with the assigned values.
  11. In all cases, the designed rise time for the system should be less than 1/2 second.
  12. Words to keep in mind are "justification," "evaluation" and "validation." I will be looking for you to justify everything you did. I will look for you to look for ways to evaluate your decisions. If you found a damping ratio and natural frequency, are there other tests you can do to check if they were good choices? Does your controller performance match the prediction? If not, how does it seem to deviate? Is the deviation systematic and repeatable? A report that shows it works for one or maybe two points, only ties the variables you use to one step input, etc., is not going to be enough to give me confidence that your design is a good one.
  13. Having said all that, I don't want a bunch of extra junk in the report. I will have to read 70 of them. A great report will convince me that you did a correct and thorough job. A bunch of extra stuff will waste my time (or your boss' time, which is much worse) and make me think you are trying to hide crappy results with a bunch of vacuous verbiage.
Group Number zeta T lag gain
1 .20 1/15 80
2 .21 1/16 81
3 .25 1/17 82
4 .23 1/18 83
5 .24 1/19 84
6 .25 1/30 85
7 .26 1/21 86
8 .27 1/22 87
9 .28 1/23 88
10 .29 1/24 89
11 .30 1/25 90
12 .31 1/26 91
13 .32 1/27 92
14 .33 1/28 93
15 .34 1/29 94
16 .35 1/30 95
17 .36 1/29 96
18 .37 1/28 97
19 .38 1/27 98
20 .39 1/26 99
21 .40 1/25 100
22 .41 1/24 101
23 .42 1/23 102
24 .43 1/22 103
25 .44 1/21 104
26 .45 1/30 105
27 .46 1/19 106
28 .47 1/18 107
29 .48 1/17 108
30 .49 1/16 109
31 .50 1/15 110
32 .51 1/16 111
33 .52 1/17 112
34 .53 1/18 113
35 .54 1/19 114
36 .55 1/30 115
37 .56 1/21 116
38 .57 1/22 117
39 .58 1/23 118
40 .59 1/24 119
41 .60 1/25 120
42 .61 1/26 121
43 .62 1/27 122
44 .63 1/28 123
45 .64 1/29 124
46 .65 1/28 125
47 .66 1/27 126
48 .67 1/26 127
49 .69 1/25 128
50 .70 1/24 129
51 .71 1/23 128
52 .72 1/22 127
53 .73 1/21 126
54 .74 1/30 125
55 .75 1/19 124
56 .76 1/18 123
57 .77 1/17 122
58 .78 1/16 121
59 .79 1/15 120
60 .80 1/16 119
61 .81 1/17 118
62 .82 1/18 117
63 .61 1/19 116
64 .63 1/30 115
65 .60 1/21 114
66 .59 1/22 113
67 .58 1/23 112
68 .55 1/24 111
69 .53 1/25 110
70 .52 1/26 109

Additional Steps

Groups with two students may do any of the following for extra credit. Groups with three members must do one of these. Additional ones are extra credit.

  • In addition to the modifications to main() and specifically the while(1) loop therein, modify any other selected parts of the code to significantly improve the performance of the system. Check how fast you can make the PWM work with your baseline code and controller before it gets flaky or how much faster you can make the 20Hz control loop. Then find something in the code that you can modify to make it faster so that it can run at a faster PWM and/or control loop before it starts running into problems.
  • Use simulink to model the real system. The plant will be continuous, but the sensing and control will be discrete.
    • Use this model to predict the steady-state error when there is no lag compensation.
    • Use this model to predict the effect of faster or slower control loops. What seems to be the slowest it can work and still be effective?
    • Use this model to predict the effect of having less resolution on the PWM, i.e., instead of a resolution from -400 to +440, check the effect of -40 to +40, etc.
  • Use simulink or other matlab tools to automatically generate the C code for the controller. Automatic code generation is becoming commonplace. Nothing is more dangerous than blindly trusting what comes out of a computer, so you have to know how the controller should work. Now that you have done that, check what simulink gives to you for code. Disclaimer: I have not done this myself and am not sure if the hc11 is a recognized target, how to do it, etc.
  • You may propose an additional component to the project if you wish. Be sure to get the instructor's approval prior to doing it if you want to receive credit for it.