Carbon Fibre / Mbed 2 deprecated Motor_test_harness

Dependencies:   Classic_PID iC_MU mbed-rtos mbed

Committer:
acodd
Date:
Wed May 27 10:07:39 2015 +0000
Revision:
3:f8a5c1cee1fa
Parent:
2:dc684c402296
Child:
4:4dafa4113982
Tidy up to variables

Who changed what in which revision?

UserRevisionLine numberNew contents of line
acodd 2:dc684c402296 1 // Control Test Harness
acodd 2:dc684c402296 2 // AC 19/05/2015. Based on MS NewMotorVelLoop
acodd 2:dc684c402296 3
acodd 2:dc684c402296 4
ms523 0:7ce0bc67f60f 5 #include "mbed.h"
ms523 0:7ce0bc67f60f 6 #include "iC_MU.h"
ms523 0:7ce0bc67f60f 7 #include "rtos.h"
ms523 0:7ce0bc67f60f 8 #include "Classic_PID.h"
ms523 0:7ce0bc67f60f 9
ms523 0:7ce0bc67f60f 10 #define _Kp 0.18 // Kp.Freq product
ms523 0:7ce0bc67f60f 11 #define _Ki 0.006 // Ki.Freq product
ms523 0:7ce0bc67f60f 12
ms523 0:7ce0bc67f60f 13 Serial pc(USBTX,USBRX);
ms523 0:7ce0bc67f60f 14
ms523 0:7ce0bc67f60f 15 // iC-MU Encoder Objects
ms523 0:7ce0bc67f60f 16 iC_MU tilt_ic_mu(p5,p6,p7,p8);
ms523 0:7ce0bc67f60f 17 iC_MU TiltPos(p5,p6,p7,p11);
ms523 0:7ce0bc67f60f 18 iC_MU pan_ic_mu(p5,p6,p7,p12);
ms523 0:7ce0bc67f60f 19 iC_MU PanPos(p5,p6,p7,p13);
ms523 1:1ad84260ff59 20
ms523 1:1ad84260ff59 21 #ifdef TARGET_LPC4088
ms523 0:7ce0bc67f60f 22 // Tilt Motor
ms523 0:7ce0bc67f60f 23 PwmOut Tilt_Motor_PWM(p27); // Purple wire
ms523 0:7ce0bc67f60f 24 DigitalOut Tilt_Motor_Direction(p28); // Yellow wire
ms523 0:7ce0bc67f60f 25 // Pan Motor
ms523 0:7ce0bc67f60f 26 PwmOut Pan_Motor_PWM(p25); // Purple wire
ms523 0:7ce0bc67f60f 27 DigitalOut Pan_Motor_Direction(p26); // Yellow wire
ms523 1:1ad84260ff59 28 #endif
ms523 1:1ad84260ff59 29
ms523 1:1ad84260ff59 30 #ifdef TARGET_LPC1768
ms523 0:7ce0bc67f60f 31 // Tilt Motor
ms523 0:7ce0bc67f60f 32 PwmOut Tilt_Motor_PWM(p23); // Purple wire
ms523 0:7ce0bc67f60f 33 DigitalOut Tilt_Motor_Direction(p24); // Yellow wire
ms523 0:7ce0bc67f60f 34 // Pan Motor
ms523 0:7ce0bc67f60f 35 PwmOut Pan_Motor_PWM(p21); // Purple wire
ms523 0:7ce0bc67f60f 36 DigitalOut Pan_Motor_Direction(p22); // Yellow wire
ms523 1:1ad84260ff59 37 #endif
ms523 0:7ce0bc67f60f 38
ms523 0:7ce0bc67f60f 39 // Joystick stuff
ms523 0:7ce0bc67f60f 40 AnalogIn Pan_Joystick(p16);
ms523 0:7ce0bc67f60f 41 AnalogIn Tilt_Joystick(p17);
ms523 0:7ce0bc67f60f 42 AnalogIn Zoom_Joystick(p18);
ms523 0:7ce0bc67f60f 43 AnalogIn Focus_Pot(p19); // The top Pot (Pot 1)
ms523 0:7ce0bc67f60f 44
ms523 0:7ce0bc67f60f 45 // Camera Stuff
ms523 0:7ce0bc67f60f 46 Serial Camera(p9,p10);
ms523 0:7ce0bc67f60f 47 InterruptIn Switch(p14);
ms523 1:1ad84260ff59 48 #ifdef TARGET_LPC4088
ms523 1:1ad84260ff59 49 DigitalOut led4(LED1),led2(LED2), led3(LED3), led1(LED4);
ms523 1:1ad84260ff59 50 #endif
ms523 1:1ad84260ff59 51 #ifdef TARGET_LPC1768
ms523 0:7ce0bc67f60f 52 DigitalOut led1(LED1),led2(LED2), led3(LED3), led4(LED4);
ms523 1:1ad84260ff59 53 #endif
ms523 1:1ad84260ff59 54
ms523 1:1ad84260ff59 55
ms523 0:7ce0bc67f60f 56 #define AUTO 1
ms523 0:7ce0bc67f60f 57 #define MANUAL 0
ms523 0:7ce0bc67f60f 58
ms523 0:7ce0bc67f60f 59 /* Kp = 0.00018, Ki = 0.000006, Kd = 0.0, 0.0001 */
ms523 0:7ce0bc67f60f 60 Classic_PID PanVelocityPID(0.00018, 0.000006, 0.0, 0.0001); //Kp, ki, kd, kvelff
acodd 2:dc684c402296 61 Classic_PID TiltVelocityPID(2, 0.000000, 0.0, 1); //Kp, ki, kd, kvelff
ms523 0:7ce0bc67f60f 62
ms523 0:7ce0bc67f60f 63 // Globals
ms523 1:1ad84260ff59 64 int ZoomPos = 10248; // Strat off at max Zoom position to avoid jerks on startup
ms523 0:7ce0bc67f60f 65 bool AutofocusFlag = true;
ms523 0:7ce0bc67f60f 66 bool ManualfocusFlag = false;
ms523 0:7ce0bc67f60f 67 bool Mode = AUTO;
acodd 3:f8a5c1cee1fa 68 bool joystick = false;
acodd 2:dc684c402296 69 bool scoping = false;
ms523 0:7ce0bc67f60f 70
ms523 0:7ce0bc67f60f 71 extern int LastPanPosition;
acodd 3:f8a5c1cee1fa 72 extern int Last_M_Position;
acodd 2:dc684c402296 73 float Pan_JoyStickDem = 0.8;
acodd 2:dc684c402296 74 float Tilt_JoyStickDem = 0.8;
acodd 2:dc684c402296 75 float Demand_Count_Rate = 0.0;
acodd 2:dc684c402296 76 float Actual_Motor_Speed = 0.0; //counts/ms
acodd 2:dc684c402296 77 float Velocity_Error = 0.0; // count/ms
acodd 2:dc684c402296 78 float P_Error = 0.0; // degrees
acodd 2:dc684c402296 79 extern float Tilt_motor_max_count_rate; //encoder counts / ms
acodd 2:dc684c402296 80
acodd 2:dc684c402296 81 extern float T_Position; // True Tilt Position (Degrees)
acodd 3:f8a5c1cee1fa 82 extern float T_Encoder_sf; // counts per degree
acodd 2:dc684c402296 83 extern int DoMove;
acodd 2:dc684c402296 84 extern float s_profile;
acodd 2:dc684c402296 85 extern float P_vel;
acodd 2:dc684c402296 86 extern float real_time;
acodd 2:dc684c402296 87 extern float T_Joy;
acodd 2:dc684c402296 88 float Joy_DeadBand = 55;
acodd 2:dc684c402296 89 float Joy_Zoom = 5; // valid numbers from 1 - 9
acodd 2:dc684c402296 90 float Time = 0.0;
acodd 2:dc684c402296 91 extern float P;
ms523 0:7ce0bc67f60f 92
ms523 0:7ce0bc67f60f 93 void PanVelocityLoop(void const *args);
ms523 0:7ce0bc67f60f 94 void TiltVelocityLoop(void const *args);
acodd 2:dc684c402296 95 void Profile(void const *args);
ms523 1:1ad84260ff59 96 int ServiceKeyboard();
ms523 0:7ce0bc67f60f 97 void UpdateCamera(float, float);
ms523 0:7ce0bc67f60f 98
ms523 0:7ce0bc67f60f 99 void isr_Switch(void)
ms523 0:7ce0bc67f60f 100 {
ms523 0:7ce0bc67f60f 101 wait_ms(1); // Wait 1ms and check if the switch is still pressed
ms523 0:7ce0bc67f60f 102 if (Switch) {
ms523 0:7ce0bc67f60f 103 wait_ms(1); // Wait another 1ms and double check the switch
ms523 0:7ce0bc67f60f 104 if (Switch) {
ms523 0:7ce0bc67f60f 105 Mode = !Mode;
ms523 0:7ce0bc67f60f 106 if(Mode == AUTO) {
ms523 0:7ce0bc67f60f 107 AutofocusFlag = true;
ms523 0:7ce0bc67f60f 108 } else {
ms523 0:7ce0bc67f60f 109 ManualfocusFlag = true;
ms523 0:7ce0bc67f60f 110 }
ms523 0:7ce0bc67f60f 111 }
ms523 0:7ce0bc67f60f 112 }
ms523 1:1ad84260ff59 113 }
ms523 0:7ce0bc67f60f 114
ms523 0:7ce0bc67f60f 115 void Anti_Lock(void const *args)
ms523 0:7ce0bc67f60f 116 {
ms523 0:7ce0bc67f60f 117 Pan_Motor_Direction = !Pan_Motor_Direction.read(); // Toggle motor direction to overcome lock protection
ms523 0:7ce0bc67f60f 118 Tilt_Motor_Direction = !Tilt_Motor_Direction.read();
ms523 0:7ce0bc67f60f 119 wait_us(10);
ms523 0:7ce0bc67f60f 120 Pan_Motor_Direction = !Pan_Motor_Direction.read();
ms523 0:7ce0bc67f60f 121 Tilt_Motor_Direction = !Tilt_Motor_Direction.read();
ms523 0:7ce0bc67f60f 122 }
ms523 0:7ce0bc67f60f 123
ms523 1:1ad84260ff59 124
ms523 1:1ad84260ff59 125 // IRQ for Rx camera interrupt
ms523 1:1ad84260ff59 126 void UART3_rxInterrupt(void)
ms523 1:1ad84260ff59 127 {
ms523 1:1ad84260ff59 128 // Create an array to read the whole message
ms523 1:1ad84260ff59 129 static int index = 0;
ms523 1:1ad84260ff59 130 static char msg[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
ms523 1:1ad84260ff59 131
ms523 1:1ad84260ff59 132 NVIC_DisableIRQ(UART3_IRQn); // Disable the interrupt
ms523 1:1ad84260ff59 133 uint32_t IRR3 = LPC_UART3->IIR;
ms523 1:1ad84260ff59 134 msg[index] = LPC_UART3->RBR; // Read the byte and put it into the next available element of the array
ms523 1:1ad84260ff59 135
ms523 1:1ad84260ff59 136 // Check to see if that is the end of the message
ms523 1:1ad84260ff59 137 if(msg[index] == 0xFF) {
ms523 1:1ad84260ff59 138 // Check to see if the response is zoom data i.e. 7 bytes long and starts with 0x90, 0x50...
ms523 1:1ad84260ff59 139 if(index == 6 && msg[0] == 0x90 && msg[1] == 0x50) {
ms523 1:1ad84260ff59 140 ZoomPos = (msg[2] & 0x0F) << 12;
ms523 1:1ad84260ff59 141 ZoomPos += (msg[3] & 0x0F) << 8;
ms523 1:1ad84260ff59 142 ZoomPos += (msg[4] & 0x0F) << 4;
ms523 1:1ad84260ff59 143 ZoomPos += (msg[5] & 0x0F);
ms523 1:1ad84260ff59 144 }
ms523 1:1ad84260ff59 145 index = 0;
ms523 1:1ad84260ff59 146 } else {
ms523 1:1ad84260ff59 147 index++;
ms523 1:1ad84260ff59 148 }
ms523 1:1ad84260ff59 149
ms523 1:1ad84260ff59 150 led3 = !led3; // Flash the LED
ms523 1:1ad84260ff59 151 NVIC_EnableIRQ(UART3_IRQn); // Enable the interrupt again
ms523 1:1ad84260ff59 152 }
ms523 1:1ad84260ff59 153
ms523 0:7ce0bc67f60f 154 int main()
ms523 0:7ce0bc67f60f 155 {
ms523 0:7ce0bc67f60f 156 // Increase the Camera baud rate
ms523 0:7ce0bc67f60f 157 Camera.baud(38400);
ms523 1:1ad84260ff59 158
ms523 1:1ad84260ff59 159 // Set up the Camera Rx Interrupt
ms523 1:1ad84260ff59 160 Camera.attach(&UART3_rxInterrupt,Serial::RxIrq);
ms523 0:7ce0bc67f60f 161
ms523 0:7ce0bc67f60f 162 // Set up the switch to toggle autofocus
ms523 0:7ce0bc67f60f 163 Switch.mode(PullDown); //Set the internal pull down resistor
ms523 0:7ce0bc67f60f 164 Switch.rise(&isr_Switch); //ISR for the switch
ms523 0:7ce0bc67f60f 165 led4 = 1; // We start in autofocus mode
ms523 0:7ce0bc67f60f 166 led1 = 1; // Turn all other LEDs off
ms523 0:7ce0bc67f60f 167 led2 = 1;
ms523 0:7ce0bc67f60f 168 led3 = 0;
ms523 1:1ad84260ff59 169
ms523 0:7ce0bc67f60f 170 // Set up the Pan motor
ms523 0:7ce0bc67f60f 171 Pan_Motor_PWM.period_us(50); // Set PWM to 20 kHz
ms523 0:7ce0bc67f60f 172 Pan_Motor_PWM = 1; // Start with motor static
ms523 0:7ce0bc67f60f 173
ms523 0:7ce0bc67f60f 174 // Set up the Tilt motor
ms523 0:7ce0bc67f60f 175 Tilt_Motor_PWM.period_us(50); // Set PWM to 20 kHz
ms523 0:7ce0bc67f60f 176 Tilt_Motor_PWM = 1; // Start with motor static
ms523 0:7ce0bc67f60f 177
ms523 0:7ce0bc67f60f 178 // Initalise Pan Velocity loop RtosTimer thread
ms523 0:7ce0bc67f60f 179 RtosTimer PanVelocityLoop_timer(PanVelocityLoop, osTimerPeriodic);
ms523 0:7ce0bc67f60f 180 PanVelocityLoop_timer.start(1); // Run at 1kHz
ms523 0:7ce0bc67f60f 181
ms523 0:7ce0bc67f60f 182 // Initalise Tilt Velocity loop RtosTimer thread
ms523 0:7ce0bc67f60f 183 RtosTimer TiltVelocityLoop_timer(TiltVelocityLoop, osTimerPeriodic);
ms523 0:7ce0bc67f60f 184 TiltVelocityLoop_timer.start(1); // Run at 1kHz
ms523 0:7ce0bc67f60f 185
ms523 0:7ce0bc67f60f 186 // Initalise Pan PID Loop
ms523 0:7ce0bc67f60f 187 PanVelocityPID.setProcessLimits(1.0, -1.0);
ms523 0:7ce0bc67f60f 188 PanVelocityPID.setSetPoint(0);
ms523 0:7ce0bc67f60f 189 LastPanPosition = pan_ic_mu.ReadPOSITION() >> 1;
ms523 0:7ce0bc67f60f 190
ms523 0:7ce0bc67f60f 191 // Initalise Tilt PID Loop
acodd 2:dc684c402296 192 TiltVelocityPID.setProcessLimits(Tilt_motor_max_count_rate, (Tilt_motor_max_count_rate*-1));
ms523 0:7ce0bc67f60f 193 TiltVelocityPID.setSetPoint(0);
acodd 3:f8a5c1cee1fa 194 Last_M_Position = tilt_ic_mu.ReadPOSITION() >> 1;
ms523 0:7ce0bc67f60f 195
ms523 0:7ce0bc67f60f 196 // Initalise Anti-Lock RtosTimer thread
ms523 0:7ce0bc67f60f 197 RtosTimer Anti_Lock_timer(Anti_Lock, osTimerPeriodic);
ms523 0:7ce0bc67f60f 198 Anti_Lock_timer.start(1000); // Run at 1Hz
acodd 2:dc684c402296 199
acodd 2:dc684c402296 200 pc.baud(921600);
ms523 1:1ad84260ff59 201
acodd 3:f8a5c1cee1fa 202 T_Position = 360 - (TiltPos.ReadPOSITION()/T_Encoder_sf); // Prime the system on startup, this is not used once running.
acodd 2:dc684c402296 203 P = T_Position; // Priming
acodd 2:dc684c402296 204 pc.printf("\n\r Startup: T_Position = %f, P = %f, \n\r", T_Position, P);
ms523 1:1ad84260ff59 205
ms523 0:7ce0bc67f60f 206 while(1) {
ms523 1:1ad84260ff59 207 // Check to see if a key has been pressed
ms523 1:1ad84260ff59 208 if(pc.readable()) {
ms523 1:1ad84260ff59 209 ServiceKeyboard();
ms523 1:1ad84260ff59 210 }
acodd 3:f8a5c1cee1fa 211 //T_Position = TiltPos.ReadPOSITION()/T_Encoder_sf;
acodd 2:dc684c402296 212 Demand_Count_Rate = TiltVelocityPID.getSetPoint();
acodd 2:dc684c402296 213
acodd 2:dc684c402296 214 if(1==0) {
acodd 2:dc684c402296 215 Velocity_Error = Demand_Count_Rate - Actual_Motor_Speed;
acodd 2:dc684c402296 216 pc.printf("\n\r Demand Ms = %f, V Error = %f, Pos = %f, Demand P = %f",Demand_Count_Rate, Velocity_Error, T_Position, P);
acodd 2:dc684c402296 217 }
acodd 2:dc684c402296 218
acodd 2:dc684c402296 219 if(scoping) {
acodd 2:dc684c402296 220 P_Error = T_Position - P;
acodd 2:dc684c402296 221 pc.printf("\n\r %f, %f, %f, %f, %f", Time, Tilt_JoyStickDem, P_Error, T_Position, P);
acodd 3:f8a5c1cee1fa 222 Time = Time + 0.025;
acodd 2:dc684c402296 223 }
acodd 2:dc684c402296 224
acodd 2:dc684c402296 225 // if(DoMove ==1) {
acodd 2:dc684c402296 226 // pc.printf("\n\r %f, %f, %f, %f",s_profile, P_vel, T_Position, real_time);
acodd 2:dc684c402296 227 // }
acodd 2:dc684c402296 228
acodd 2:dc684c402296 229
ms523 1:1ad84260ff59 230
acodd 3:f8a5c1cee1fa 231 Thread::wait(25);
ms523 0:7ce0bc67f60f 232 // Update the Zoom and Focus Demands
acodd 2:dc684c402296 233 //UpdateCamera(Zoom_Joystick.read(),Focus_Pot.read());
acodd 2:dc684c402296 234
ms523 1:1ad84260ff59 235 //pc.printf("\n\r %d ",tiltPosition);
acodd 2:dc684c402296 236 //Thread::wait(50);
acodd 2:dc684c402296 237
ms523 1:1ad84260ff59 238
acodd 2:dc684c402296 239 // Apply Offset
acodd 2:dc684c402296 240 Pan_JoyStickDem = Pan_Joystick.read() - 0.5;
acodd 2:dc684c402296 241 Tilt_JoyStickDem = Tilt_Joystick.read() - 0.5;
acodd 2:dc684c402296 242 // Square the demand for pan joystick profile & check if neg
acodd 2:dc684c402296 243 if(Pan_JoyStickDem > 0) {
acodd 2:dc684c402296 244 Pan_JoyStickDem = Pan_JoyStickDem * Pan_JoyStickDem;
acodd 2:dc684c402296 245 } else {
acodd 2:dc684c402296 246 Pan_JoyStickDem = Pan_JoyStickDem * Pan_JoyStickDem * -1;
acodd 2:dc684c402296 247 }
acodd 2:dc684c402296 248
acodd 2:dc684c402296 249 Pan_JoyStickDem *= 10000; // Apply scalefactor
acodd 2:dc684c402296 250 Tilt_JoyStickDem *= 10000; // Apply scalefactor
acodd 2:dc684c402296 251
acodd 2:dc684c402296 252 if ((Tilt_JoyStickDem * Tilt_JoyStickDem) < (Joy_DeadBand * Joy_DeadBand)){
acodd 2:dc684c402296 253 Tilt_JoyStickDem = 0; //Apply Deadband
acodd 2:dc684c402296 254 }
acodd 2:dc684c402296 255
acodd 2:dc684c402296 256 Tilt_JoyStickDem = Tilt_JoyStickDem / Joy_Zoom;
acodd 2:dc684c402296 257
ms523 0:7ce0bc67f60f 258 if(joystick) {
ms523 1:1ad84260ff59 259 PanVelocityPID.setSetPoint((int)Pan_JoyStickDem); // Read the joystick and apply the gain
ms523 1:1ad84260ff59 260 TiltVelocityPID.setSetPoint((int)Tilt_JoyStickDem); // Read the joystick and apply the gain
acodd 2:dc684c402296 261 } else {
acodd 2:dc684c402296 262
acodd 2:dc684c402296 263 T_Joy = -Tilt_JoyStickDem / 100;
acodd 2:dc684c402296 264
ms523 1:1ad84260ff59 265 }
ms523 1:1ad84260ff59 266
ms523 0:7ce0bc67f60f 267 if(AutofocusFlag) {
ms523 0:7ce0bc67f60f 268 // Turn on the autofocus
ms523 1:1ad84260ff59 269 led1 = 1; // Turn the LED on to show we are in auto-focus mode
ms523 0:7ce0bc67f60f 270 Camera.putc(0x81); // Camera
ms523 0:7ce0bc67f60f 271 Camera.putc(0x01); // Turn on auto-focus cmd
ms523 0:7ce0bc67f60f 272 Camera.putc(0x04);
ms523 0:7ce0bc67f60f 273 Camera.putc(0x38);
ms523 0:7ce0bc67f60f 274 Camera.putc(0x02);
ms523 0:7ce0bc67f60f 275 Camera.putc(0xFF); // Terminator
ms523 0:7ce0bc67f60f 276 AutofocusFlag = false;
ms523 0:7ce0bc67f60f 277 Mode = AUTO;
ms523 0:7ce0bc67f60f 278 }
ms523 0:7ce0bc67f60f 279 if(ManualfocusFlag) {
ms523 0:7ce0bc67f60f 280 // Turn on Manual focus
ms523 1:1ad84260ff59 281 led1 = 0; // Turn the LED off to show we are in manual-focus mode
ms523 0:7ce0bc67f60f 282 Camera.putc(0x81); // Camera
ms523 0:7ce0bc67f60f 283 Camera.putc(0x01); // Turn on manual-focus cmd
ms523 0:7ce0bc67f60f 284 Camera.putc(0x04);
ms523 0:7ce0bc67f60f 285 Camera.putc(0x38);
ms523 0:7ce0bc67f60f 286 Camera.putc(0x03);
ms523 0:7ce0bc67f60f 287 Camera.putc(0xFF); // Terminator
ms523 0:7ce0bc67f60f 288 ManualfocusFlag = false;
ms523 0:7ce0bc67f60f 289 Mode = MANUAL;
ms523 1:1ad84260ff59 290 }
ms523 0:7ce0bc67f60f 291 }
ms523 0:7ce0bc67f60f 292 }
ms523 0:7ce0bc67f60f 293
ms523 1:1ad84260ff59 294 /*
ms523 1:1ad84260ff59 295 // Increase the serial baud rate
ms523 1:1ad84260ff59 296 // pc.baud(921600);
ms523 0:7ce0bc67f60f 297
ms523 1:1ad84260ff59 298 while(1) {
ms523 1:1ad84260ff59 299 Thread::wait(100);
ms523 0:7ce0bc67f60f 300
ms523 1:1ad84260ff59 301 if(pc.readable()) {
ms523 1:1ad84260ff59 302 ServiceKeyboard();
ms523 1:1ad84260ff59 303 }
ms523 1:1ad84260ff59 304
ms523 1:1ad84260ff59 305 if(Demand) {
ms523 1:1ad84260ff59 306 pc.printf("\n\r %0.3f ",PanVelocityPID.getSetPoint());
ms523 1:1ad84260ff59 307 }
ms523 1:1ad84260ff59 308 }
ms523 0:7ce0bc67f60f 309 }*/
acodd 2:dc684c402296 310
acodd 2:dc684c402296 311
acodd 2:dc684c402296 312