At the outset, I have a few goals for this project, but a big one is try my skills at a realtime inferencing project using the jetson and get familar with the TensorRT framework.
So why this project?
- Realtime motion control and PID usage
- Machine learning
- Electrical design
- Mechanical design
For the machine learning piece I want to start by doing realtime object tracking, and after that focus on reinforcement learning. One of my hobbies is flying RC planes, and a dream of mine is to have a plane that can track another plane like in a dogfight. This small project is a good first move in that direction.
I started by thinking about designing my own turret, and realized that wasn’t what I wanted to focus on, so I printed this amazing camera gimbal.
Hardware list:
Link to full bill of materials
- 1 spool of PLA filament
- 2 stepper motors – I had leftovers from an old 3D printer
- 2 standard 3D print drivers you can get for a few bucks on Amazon
- 2 switching power supplies with adjustable voltage
- 2 end stops
- Assorted screws – #6 5/8in, #6 3/4in, #6 1/2in, #4 1/2in
- 4x bearings
- Jetson Nano
- 1 meter CSI camera ribbon cable
- Wide angle camera and imx219 camera (8mp camera)
Long term I don’t plan on using the power supplies or the motor drives here, they are too weak for any high-load use but they work for testing. I printed all the parts in about 4 days of continuous printing on my Prusa MK2, and had to reprint the largest gear. I bought the bearings on Amazon, and was able to get the screws from my local hardware store. Assembly was quite easy, I used a fast-set 2part epoxy for the parts.
To test the system I wired the motors like below
I used the following code to test the stepper speeds and the microstepping to test a few things:
- Stepping speed overall
- Stepping smoothness
- Dropped steps
The dropped steps are important since I don’t have any rotary encoders. If either axis does a full rotation the wires will snag, so I need a way to determine the orientation. I was initially thinking I could count the total steps in either direction, but I have been dropping a lot of steps at the higher drive frequencies, so I may go with endstops, either mechanical or optical, most likely optical so I don’t have a hard crash and can ramp down the motors.
import time
import Jetson.GPIO as GPIO
Z_MOTOR_STEP = 21 # HEADER PIN 21
Z_MOTOR_DIR = 22 # HEADER PIN 22
Y_MOTOR_STEP = 23 # HEADER PIN 23
Y_MOTOR_DIR = 24 # HEADER PIN 24
delay = 0.001
steps = 100
# Set the numberings to be the same as the PCB board label numbers
GPIO.setwarnings(True)
GPIO.setmode(GPIO.BOARD)
# Set pin modes
# Z motor is rotation about the base
GPIO.setup(Z_MOTOR_STEP, GPIO.OUT, initial=GPIO.LOW)
GPIO.setup(Z_MOTOR_DIR, GPIO.OUT, initial=GPIO.LOW)
# Y motor is tilt
GPIO.setup(Y_MOTOR_STEP, GPIO.OUT, initial=GPIO.LOW)
GPIO.setup(Y_MOTOR_DIR, GPIO.OUT, initial=GPIO.LOW)
for step in range(0, steps):
time.sleep(delay)
GPIO.output(Z_MOTOR_STEP, GPIO.HIGH)
GPIO.output(Y_MOTOR_STEP, GPIO.HIGH)
time.sleep(delay)
GPIO.output(Z_MOTOR_STEP, GPIO.LOW)
GPIO.output(Y_MOTOR_STEP, GPIO.LOW)
time.sleep(1)
# Change direction
GPIO.output(Z_MOTOR_DIR, GPIO.HIGH)
GPIO.output(Y_MOTOR_DIR, GPIO.HIGH)
for step in range(0, steps):
time.sleep(delay)
GPIO.output(Z_MOTOR_STEP, GPIO.HIGH)
GPIO.output(Y_MOTOR_STEP, GPIO.HIGH)
time.sleep(delay)
GPIO.output(Z_MOTOR_STEP, GPIO.LOW)
GPIO.output(Y_MOTOR_STEP, GPIO.LOW)
GPIO.cleanup([Z_MOTOR_DIR, Z_MOTOR_STEP, Y_MOTOR_DIR, Y_MOTOR_STEP])