Lab 1: Hello PD
Goal: Build a robot arm that you can program PD control on.
Link to the Lab document.
Step 0. Setup
Install Git for your OS. Windows, Mac, Linux (keep in mind if you are using Debian, Ubuntu, etc). We will use Git for retrieving starter code, and version control.
Install VSCode. VSCode is a convenient IDE where you will do your code development.
Install the PlatformIO extension for VSCode, a native Arduino/Teensyduino development IDE for VSCode. (Might take several minutes on Windows - check the bottom bar in VSCode for status)
Step 1. Assemble motor to base
Step 2. Fasten feet to base
Ignore that there’s a whole robot arm attached in the video.
Step 3. Attach dial to motor
Step 4. Connect and calibrate electronics
ELECTRONICS SAFETY: Make sure to separate the PCB from the metal base before turning on the power, otherwise the circuit will short! Either elevate the PCB above the base with the screws provided, or place the PCB next to the metal base on the table.
NOTE: There are two CAN buses on the PCB that can be instantiated using C610Bus (take a look at the head of the file to see how it works). The yellow connectors on either side of the PCB correspond to each bus. For this lab, you will be using the back-side CAN bus, close to the where it says “BATTERY” on the PCB. Plug your motor in one of the yellow connectors on the back side there.
Turn on the system: press the power button on the PCB shield.
Calibrate: Press and hold the button on the C610 motor controller until the motor starts moving and release.
Wait until the C610 motor controller restarts.
Set ID: Click the button on the C610 controller, then a little while later (half second or so) press the button again. The light should flash green.
The light should now flash once every 2 seconds or so. The number of blinks indicates which ID it is. For example two blinks every 2 seconds indicates ID=2.
Important: To set a motor controller to a certain ID, click (short press) press to put the motor controller into id-setting mode, then click N more times in quick succession, where N is the desired ID. Eg, for a desired ID of 3, press 3 more times after the first click.
Step 5. Examine and run the starter code
WARNING To stop code, press s
inside the terminal instead of ^C. Using ^C will lead to undefined behavior when you upload new code, or run the code again.
Git clone the starter code
git clone https://github.com/cs123-stanford/lab_1_hello_pd.git
cd lab_1_hello_pd
git submodule init
git submodule update
Open in VSCode, and upload to Teensy (refer to video).
Examine where in the code the motor angle and velocity are read in
src/main.cpp
. Examine where the motor is commanded.
NOTE In Arduino/Teensyduino code, there are two central functions to pay attention to. First, there is the setup()
function, which runs once when the code is uploaded to the microcontroller, and sets up the configuration. Next, there is the loop()
function, which runs continuously, like a while True
loop before you stop the code. Most other functions, while still important, can be considered helper functions. Pay particular attention to the updateCmd()
and updateState()
functions, which update a MotorState
object that is defined in a struct.
DELIVERABLE: Before running your code, write what you understand about the ``loop()`` function for this code in your Lab Document. What gets updated on each iteration? How does updating a MotorState object correspond to actually changing the physical commanded current of the motor?
Upload starter code to Teensy (right arrow icon in blue bar of VSCode or click the ant icon, then upload)
Open the serial monitor in VSCode (icon that looks like a plug in bottom bar of VSCode or click ant icon, then monitor)
Click into the serial monitor area and then press the key s to make the Teensy start printing out the angle and velocity of the connected motor.
Press
s
again to stop the program (use this in place of ^C, to start and stop the program). If you want to rerun the code, upload again or unplug and replug your computer from the Teensy.
Step 6. Run bang-bang control
Examine the function
bang_bang_control()
insrc/main.cpp
and understand what it does. It is called in theupdateCmd()
function.updateCmd()
is then called every iteration ofloop()
.Uncomment the bang-bang code in
updateCmd()
and upload.Observe the effects of changing the current command to something else. Reminder, bang_bang_control returns a commanded current.
FEEL how the controller behaves. Move the dial by hand and see how the controller reacts.
Example bang-bang control.
DELIVERABLE: Take a video of your bang bang control to upload to Gradescope with your submission
Step 7. Write P proportional control
Comment out the bang-bang controller.
Take a look at the pd_control function in
src/main.cpp
. Notice that there are two parts summed together: proportional_control and derivative_control. They are the individual terms of the PD control law.Complete the proportional_control function in
src/main.cpp
. Your function should return an electrical current command (100mA, 200mA etc) using the PD control law using the following update equation. In this case, we are not conducting any damping on the control current, so leave that as 0.
Questions:
Start with Kp = 1000.0 and leave Kd as is. Don’t forget the negative signs!
Upload code to Teensy
FEEL the effect of the P controller.
What happens when you rotate the disc just a little bit away from the target position? What happens when you rotate it a lot away from the target position? Do you feel the motor torque increase and then flatten out as you rotate the disc?
What changes when you change Kp?
DELIVERABLE: Answer these last two questions in your lab document
Step 8. Write PD position control
Next, complete the derivative_control in
src/main.cpp
. This should work with your proportional_control in pd_control to create a more full PD controller. Again, follow the above update equation, outputting an electrical current intau
.
Questions:
After adding in the derivative term, use Kp = 1000.0 and Kd = 10.0 to start. Don’t forget the negative signs! How does this controller perform compared to just P control?
Upload code to Teensy
FEEL the effect of the PD controller.
Change around the values for Kp and Kd, experimenting with how they change the performance. What happens now when you rotate the disc farther from the target position? Why does adding the derivative term help the controller’s performance? Find the optimal Kp and Kd values.
DELIVERABLE: Answer the above questions in your lab document, and report your chosen Kp and Kd values. Take a video of your working PD controller to upload to Gradescope
Step 9. Experiment with different parameters
Note: Some of these steps will cause the output disc to go unstable and violently shake, be prepared!
For each of these situations (except the ones that go unstable), rotate the disc around with your hand to get a physical sense for the PD behavior. Report on your findings for each of these in your lab document.
Keeping Kd constant (0), experiment with Kp = -100 and Kp = 5000. Discuss with your partner how each feels. Report how Kp and stiffness related?
Keeping Kp constant (1000), experiment with different Kd values from -10 to 1000. Report what happens.
Report what happens when Kp is too high. Try Kp=50000 and Kd=100.
Report what happens when Kd is too high. Try Kp=0 and Kd=100000.
Report what happens with just moderate damping. Try Kp=0 and Kd=100.
DELIVERABLE: Report your findings in your lab document
The expected behavior is that higher Kp values will make the position control more stiff while higher Kd values will make the motor slower to achieve the desired position. If either gain is too high or is negative, the motor will go unstable.
Step 10. Experiment with different loop rates
Report on your findings for each of these in your lab document #. Examine where the code is checking if it’s time to issue another control update. #. Change the update rate to 4Hz with Kp=1000 and Kd=100 to observe instability. Reminder, 1Hz = 1/seconds.
DELIVERABLE: Report how increasing/decreasing the update frequency affects the controller’s performance.
WARNING, decreasing the update frequency by too much can cause dangerous behavior.
Step 11. Program periodic motion
Set the update rate back to 200Hz (5ms interval).
Program the motor to track a sinusoidal position, like the psuedocode below.
float time = millis() / 1000.0
position_target = sin(time)
Play around with different frequencies. How high can you raise the frequency before the motor no longer moves as much as you expect?
DELIVERABLE: Take a video to upload to Gradescope with your submission of periodic motion
Fun fact, the maximum frequency you can go before the motor moves to only 71% (-3dB) of the intended motion is called the bandwidth.
Congrats on finishing your first lab!