This file combines the Encoder, Motor, and TouchPanel drivers we created for previous labs with the kinematic and dynamic analysis of the platform from previous labs to balance a ball on the platform. More...
Functions | |
def | main.nFaultISR (self, pin) |
Variables | |
main.TPD = touchy(pyb.Pin.board.PA7, pyb.Pin.board.PA1, pyb.Pin.board.PA6, pyb.Pin.board.PA0, 0.959, 3.937, 3.480, 1.979) | |
Initialize touch Panel and corresponding pins. | |
int | main.x = 0 |
x position of ball on platform | |
int | main.x_dot = 0 |
x velocity of ball on platform | |
int | main.y = 0 |
y position of ball on platform | |
int | main.y_dot = 0 |
y velocity of ball on platfrom | |
main.Encoder1APin = pyb.Pin(pyb.Pin.cpu.B6, pyb.Pin.IN) | |
Encoder 1 pin. | |
main.Encoder1BPin = pyb.Pin(pyb.Pin.cpu.B7, pyb.Pin.IN) | |
Encoder 1 pin. | |
main.Encoder2APin = pyb.Pin(pyb.Pin.cpu.C6, pyb.Pin.IN) | |
Encoder 2 pin. | |
main.Encoder2BPin = pyb.Pin(pyb.Pin.cpu.C7, pyb.Pin.IN) | |
Encoder 2 pin. | |
int | main.TimerNum1 = 4 |
Encoder 1 timer number. | |
int | main.TimerNum2 = 8 |
Encoder 2 timer number. | |
int | main.Period = 65535 |
Timer period that both encoders will use. | |
int | main.Prescaler = 0 |
Timer prescaler that both encoders will use. | |
main.Encoder1 = EncoderDriver(Encoder1APin, Encoder1BPin, TimerNum1, Prescaler, Period) | |
Encoder 1 object. | |
main.Encoder2 = EncoderDriver(Encoder2APin, Encoder2BPin, TimerNum2, Prescaler, Period) | |
Encoder 2 object. | |
int | main.theta_x = 0 |
Angular position about x axis. | |
int | main.theta_dot_x = 0 |
Angular velocity about x axis. | |
int | main.theta_y = 0 |
Angular position about y axis. | |
int | main.theta_dot_y = 0 |
Angular velocity about y axis. | |
main.pin_nSLEEP = pyb.Pin(pyb.Pin.cpu.A15, pyb.Pin.OUT_PP) | |
CPU pin which is connected to DRV8847 nSLEEP pin. | |
main.pin_IN1 = pyb.Pin.board.PB4; | |
CPU pin which is connected to DRV8847 IN1 pin. | |
main.pin_IN2 = pyb.Pin.board.PB5; | |
CPU pin which is connected to DRV8847 IN2 pin. | |
main.pin_IN3 = pyb.Pin.board.PB0; | |
CPU pin which is connected to DRV8847 IN3 pin. | |
main.pin_IN4 = pyb.Pin.board.PB1; | |
CPU pin which is connected to DRV8847 IN4 pin. | |
main.time = pyb.Timer(3,freq = 20000); | |
Timer object used for PWM generation. | |
main.Motor1 = MotorDriver(pin_nSLEEP, pin_IN1, pin_IN2, time, 1, 2) | |
Motor 1 object. | |
main.Motor2 = MotorDriver(pin_nSLEEP, pin_IN3, pin_IN4, time, 3, 4) | |
Motor 2 object. | |
main.nFaultInt = pyb.ExtInt(pyb.Pin.cpu.B2, pyb.ExtInt.IRQ_FALLING, pyb.Pin.PULL_UP, nFaultISR) | |
External interrupt on nFault pin. | |
main.FaultInt | |
float | main.K1 = -3.0 |
Gain for velocity. | |
int | main.K2 = -.075 |
Gain for angular velocity. | |
int | main.K3 = -30 |
Gain for position. | |
float | main.K4 = -4.2 |
Gain for angular position. | |
float | main.K_duty = 13.3454 |
Conversion factor from motor torque to duty cycle (K_duty = R/(Vdc * Kt) = 2.21 ohms /(12V * 12.8 mN/A)) | |
int | main.GearRatio = 4 |
Gear ratio between motor and encoder (12 teeth on motor gear and 48 teeth on encoder gear; 48/12 = 4) | |
int | main.old_time1 = 0 |
Placeholder for last time1. | |
int | main.old_time2 = 0 |
Placeholder for last time2. | |
int | main.new_time1 = utime.ticks_us() / 1000000 |
Most recent time1. | |
int | main.period1 = new_time1 - old_time1 |
Time since last call that is used as a period for velocity calucations. | |
int | main.y_new = TPD.y_read() / 1000 |
Y-axis reading in meters. | |
main.theta_x_new = Encoder1.get_position() * (math.pi / 1000) | |
Encoder 1 angular position in radians. | |
tuple | main.Torque_A = ((-K1 * y_dot) - (K2 * theta_dot_x) - (K3 * y) - (K4 * -theta_x)) |
Torque value for motor 1. | |
main.Duty_Cycle_A = int(K_duty * Torque_A * GearRatio) | |
Duty cycle for motor 1. | |
main.nFault | |
int | main.new_time2 = utime.ticks_us() / 1000000 |
Most recent time2. | |
int | main.period2 = new_time2 - old_time2 |
Time since last call that is used as a period for velocity calucations. | |
int | main.x_new = TPD.x_read() / 1000 |
X-axis reading in meters. | |
main.theta_y_new = Encoder2.get_position() * (math.pi / 1000) | |
Encoder 2 angular position in radians. | |
tuple | main.Torque_B = ((-K1 * x_dot) - (K2 * theta_dot_y) - (K3 * x) - (K4 * -theta_y)) |
Torque value for motor 2. | |
main.Duty_Cycle_B = int(K_duty * Torque_B * GearRatio) | |
Duty cycle for motor 2. | |
This file combines the Encoder, Motor, and TouchPanel drivers we created for previous labs with the kinematic and dynamic analysis of the platform from previous labs to balance a ball on the platform.
First we initialize the touchpad with device specific values. Then, we initialzie the two encoders and two motors. We also create an interrupt and interrupt service routine to prevent any mechanical faults from causing damage. Lastly, we continuously run the two motor operations, which are similar. The motor operations calculate a period, reads from the touch panel to find position and velocity, and reads from the encoder to find angular position and velocity. It then applies the gains to the values found to find the motor torque. Lastly, it converts the motor torque to a duty cycle using the gear ratio and the motor torque conversion factor, which is then set as the motor's duty cycle.