2.12/2.120 Intro to Robotics
Spring 20241
Below is an image of the 2-DoF robot arm you will assemble. Completing this section should take less than 20 minutes, so please ask for help if you feel like you are taking longer! We want you to have enough time to complete the remaining sections.
Materials:
- 2 arm links (low-side U-channel)
- 3 base mounts (U-channel)
- 2 motors (60 RPM)
- 2 hubs
- socket head bolts (M4)
- hex nuts (M4)
- marker holder
Steps:
-
Attach the 2 motors on either end of a single arm link.
-
Add the hubs onto each shaft using 2 set screws.
-
Attach the base made of 3 U-channels to one of the hubs.
-
Attach a new arm to the other hub and attach the marker holder to the end of that arm.
-
Use two clamps to hold the base down to the table.
Similar to Lab 1, we also need to wire and validate the microcontroller, motors, and encoders.
-
Plug the microcontroller in the breadboard so that the USB-C port is near the edge of the breadboard.
-
Use solid wires to connect the
3.3V
to both+
rails andGND
to both-
rails.What is a rail?
Rails on a breadboard refer to the two long strips labeled
+
and-
on either side. They are typically located between red and blue lines parallel to the rails. -
Open the VSCode application. Click "File" on the upper-left corner then click "New Window".
-
Clone this repository.
-
Run
blink_test.cpp
. The onboard LED should change colors.How do I put the microcontroller in download mode again?
Press and hold
BOOT
. ClickRST
while still holding downBOOT
. Let go ofBOOT
.
-
Wire the motors according to
include/pinout.h
. Remember to wire theGND
pin of the motor driver to the-
rail. -
Connect the button as an emergency stop to go between the motor driver and the power supply.
-
Reduce the power supply output to about
4V
. Remember, the motors are powerful. Always keep the workspace clear of obstacles (laptops) and hold on to the emergency stop button. -
Confirm that the motor driver has power. The yellow
PWR
LED should be on. If not, turn on the emergency stop button. -
Push and hold the
M1A
,M1B
,M2A
,M2B
buttons on the motor driver one at a time to check that the motors can spin in both directions.M1
should correspond to the motor attached to the base. -
Turn off the emergency stop button. The emergency stop should always be off unless the motors need to move.
-
Make the arm point straight up in full extension. This is the default position the arm should be in before running any code.
-
Run
motor_drive_test.cpp
. You should see both motors turn slightly in both directions at two different speeds.Nothing is happening?
Check that the motor driver has power by looking at the yellow
PWR
LED. If not, turn on the emergency stop button. -
Turn off the emergency stop button. The motor driver does not need power for the encoder wiring and validation.
- Wire the encoders according to
include/pinout.h
. Use an extension cable for encoder 2. - Use zip ties to attach the wires encoder 2 to link 1 so that
M1
can rotate freely without snagging wires. - Run
encoder_basic_test.cpp
and open the Serial Monitor. Observe which turn directions make the encoder count increase and think about why this is the case. - Run
encoder_test.cpp
. Confirm that the position increases when turning link 1 counter-clockwise looking down at the table and decreases when turning link 2 counter-clockwise looking down at the table.
✅ CHECKOFF 1 ✅ |
---|
Demonstrate encoder_test.cpp to a TA or LA! |
Before you leave, please fill out https://tinyurl.com/212-feedback.
✅ CHECKOFF 2 ✅ |
---|
Show the feedback form completion screen to a TA or LA. |
Now that we have a validated 2-DoF robot, let's add a joystick to control it.
- Wire the joystick according to the schematic on the board.
- To validate that you can read the joystick input, run
joystick_test.cpp
and open the Serial Monitor. You should see joystick readings in the range[-1, 1)
.
With the joystick in place, we can then use code to connect the joystick reading to the robot motion.
-
Open
include/joystick.h
and define astruct
to store thex
andy
values of a joystick reading as integers.What is a struct?
A structure or
struct
is a user-defined data type that can group members of possibly different types into a single type. An example usage is shown below.struct Student { int id; float gpa; }; Student bob(1, 2.0); // Initializes a Student variable called bob with id 1 and gpa 2.0 bob.gpa = 2.3; // Updates the gpa member of bob to 2.3 Serial.printf("GPA: %.2f\n", bob.gpa); // Prints the new gpa 2.3 in the Serial Monitor
-
Open
lab_code/joystick.cpp
and complete theTODO
s. -
Open
test_code/joystick_test.cpp
and complete theTODO
s. -
Move
joystick_test.cpp
andjoystick.cpp
to therobot/
directory. -
Run the new
joystick_test.cpp
and open the Serial Monitor. Confirm that your joystick readings are the same as before.
Open lab_code/drawing.cpp
and complete all the TODO
s. At a high level, the code should do the following:
- reads the joystick
- scales the joystick reading from
[-1, 1)
to[-pi/2, pi/2)
- feeds the joystick reading to a position setpoint
- smoothes the position setpoint using exponential smoothing
- drives the motor using a PID controller
Simply put, the x-axis of the joystick controls the velocity of motor 1 and the y-axis of the joystick controls the velocity of motor 2. This is joint space!
Attach a marker to the end of your 2-DoF robot and try drawing a straight line on your whiteboard. Make sure to move all 3 files drawing.cpp
, joystick.cpp
, and kinematics.cpp
from lab_code/
to robot/
.
✅ CHECKOFF 2 ✅ |
---|
Show your work of art to a TA or LA! |
Footnotes
-
Version 1 - 2020: Rachel Hoffman
Version 2 - 2024: Phillip Daniel
Version 3 - 2024: Ravi Tejwani, Kentaro Barhydt
Version 4 - 2024: Jinger Chong, Josh Sohn ↩