Test Program

Dependencies:   Classic_PID iC_MU mbed-rtos mbed

Files at this revision

API Documentation at this revision

Comitter:
ms523
Date:
Thu Apr 02 07:35:39 2015 +0000
Child:
1:1ad84260ff59
Commit message:
Working as demo'd in the end of March sprint review.

Changed in this revision

Classic_PID.lib Show annotated file Show diff for this revision Revisions of this file
PanVelocityLoop.cpp Show annotated file Show diff for this revision Revisions of this file
ServiceKeyboard.cpp Show annotated file Show diff for this revision Revisions of this file
TiltVelocityLoop.cpp Show annotated file Show diff for this revision Revisions of this file
UpdateCamera.cpp Show annotated file Show diff for this revision Revisions of this file
iC_MU.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Classic_PID.lib	Thu Apr 02 07:35:39 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/teams/Vitec-Group/code/Classic_PID/#7b42de70b65f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PanVelocityLoop.cpp	Thu Apr 02 07:35:39 2015 +0000
@@ -0,0 +1,45 @@
+#include "mbed.h"
+#include "iC_MU.h"
+#include "rtos.h"
+#include "Classic_PID.h"
+
+// Define limits for zero crossing
+// These values should allow operation upto 3750 RPM
+#define bits 18                 // The number of bits we want to use
+#define OneTurn (1<<bits)       // 262144 counts per rev
+#define Lower (1<<(bits-5))     // 8192 counts = 11.25 degrees
+#define Upper OneTurn - Lower   // 262144 - 8192 = 253952
+
+extern iC_MU pan_ic_mu;
+extern PwmOut Pan_Motor_PWM;
+extern DigitalOut Pan_Motor_Direction;
+extern Classic_PID PanVelocityPID;
+
+int LastPanPosition = 0;
+
+void PanVelocityLoop(void const *args)
+{
+    int Position = pan_ic_mu.ReadPOSITION() >> (19 - bits); // Read the current position from the iC-MU and bitshift to reduce noise
+    int Velocity = Position - LastPanPosition;              // Calculate change in position (i.e. Velocity)
+    float Duty_Cycle = 0.0;
+
+    // Check to see if we have gone past the index point
+    if(Position < Lower & LastPanPosition > Upper) {        // We have gone over the index point in 1 direction
+        Velocity += OneTurn;
+    } else if(Position > Upper & LastPanPosition < Lower) { // We have gone over the index point in the other direction
+        Velocity -= OneTurn;
+    }  
+    LastPanPosition = Position;                             // Update new position from next time
+
+    PanVelocityPID.setProcessValue(Velocity);               // Pass the Velocity onto the PID loop
+    //Duty_Cycle = VelocityPID.compute_ff();                  // Adjust the PWM output with no feed forward
+    Duty_Cycle = PanVelocityPID.compute();
+
+    if(Duty_Cycle < 0) {
+        Pan_Motor_Direction = 0;
+        Pan_Motor_PWM = 1 - (Duty_Cycle * -1.0);
+    } else {
+        Pan_Motor_Direction = 1;
+        Pan_Motor_PWM = 1 - Duty_Cycle;
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ServiceKeyboard.cpp	Thu Apr 02 07:35:39 2015 +0000
@@ -0,0 +1,98 @@
+#include "mbed.h"
+#include "iC_MU.h"
+#include "rtos.h"
+#include "Classic_PID.h"
+
+extern Serial pc;
+extern Classic_PID PanVelocityPID;
+extern Classic_PID TiltVelocityPID;
+
+extern bool joystick;
+
+// Returns the new set point entered via the keyboard
+int ServiceKeyboard ()
+{
+    return(1);
+}
+    /*
+    int key;                                            // The keypress by the user
+    int value = 0;                                      // The variable to return
+
+    key = pc.getc();                                    // Read the intial keypress
+
+    if (key == 'j') {
+        joystick = !joystick;
+        if(joystick) {
+            pc.printf("\n\rJoystick");
+        } else {
+            pc.printf("\n\rPC");
+        }
+    } 
+    // Set Velocity for Pan and Tilt here...
+    else if(key == 'p') {
+        // We are going to set the speed of pan...
+        pc.printf("\n\r New Pan Vel: ");
+        key = pc.getc();
+        if (key == 0x1B) {
+            if(pc.getc() == 0x4F) {
+                if(pc.getc() == 0x53) {
+                    pc.printf("-");
+                    do {
+                        key = pc.getc();                            // Wait for a keypress
+                        if(key >= '0' && key <= '9') {              // Check it is a number
+                            value *= 10;                            // Index the old number
+                            value += (key - '0');                   // Add on the new number
+                            pc.printf("%c",key);                    // Display the new number
+                        }
+                    } while(key != 0x0D);
+                    PanVelocityPID.setSetPoint(value * -1);
+                }
+            }
+        } else if(key >= '0' && key <= '9') {                      // Check it is a number
+            pc.printf("%c",key);
+            value = (key - '0');
+            do {
+                key = pc.getc();                            // Wait for a keypress
+                if(key >= '0' && key <= '9') {              // Check it is a number
+                    value *= 10;                            // Index the old number
+                    value += (key - '0');                   // Add on the new number
+                    pc.printf("%c",key);                    // Display the new number
+                }
+            } while(key != 0x0D);
+            PanVelocityPID.setSetPoint(value);
+        }
+    } else if(key == 't') {
+        // We are going to set the speed of tilt...
+        pc.printf("\n\r New Tilt Vel: ");
+        key = pc.getc();
+        if (key == 0x1B) {
+            if(pc.getc() == 0x4F) {
+                if(pc.getc() == 0x53) {
+                    pc.printf("-");
+                    do {
+                        key = pc.getc();                            // Wait for a keypress
+                        if(key >= '0' && key <= '9') {              // Check it is a number
+                            value *= 10;                            // Index the old number
+                            value += (key - '0');                   // Add on the new number
+                            pc.printf("%c",key);                    // Display the new number
+                        }
+                    } while(key != 0x0D);
+                    TiltVelocityPID.setSetPoint(value * -1);
+                }
+            }
+        } else if(key >= '0' && key <= '9') {                      // Check it is a number
+            pc.printf("%c",key);
+            value = (key - '0');
+            do {
+                key = pc.getc();                            // Wait for a keypress
+                if(key >= '0' && key <= '9') {              // Check it is a number
+                    value *= 10;                            // Index the old number
+                    value += (key - '0');                   // Add on the new number
+                    pc.printf("%c",key);                    // Display the new number
+                }
+            } while(key != 0x0D);
+            TiltVelocityPID.setSetPoint(value);
+        }
+    }
+    return(1);
+}*/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TiltVelocityLoop.cpp	Thu Apr 02 07:35:39 2015 +0000
@@ -0,0 +1,44 @@
+#include "mbed.h"
+#include "iC_MU.h"
+#include "rtos.h"
+#include "Classic_PID.h"
+
+// Define limits for zero crossing
+// These values should allow operation upto 3750 RPM
+#define bits 18                 // The number of bits we want to use
+#define OneTurn (1<<bits)       // 262144 counts per rev
+#define Lower (1<<(bits-5))     // 8192 counts = 11.25 degrees
+#define Upper OneTurn - Lower   // 262144 - 8192 = 253952
+
+extern iC_MU tilt_ic_mu;
+extern PwmOut Tilt_Motor_PWM;
+extern DigitalOut Tilt_Motor_Direction;
+extern Classic_PID TiltVelocityPID;
+
+int LastTiltPosition = 0;
+
+void TiltVelocityLoop(void const *args)
+{
+    int Position = tilt_ic_mu.ReadPOSITION() >> (19 - bits);// Read the current position from the iC-MU and bitshift to reduce noise
+    int Velocity = Position - LastTiltPosition;             // Calculate change in position (i.e. Velocity)
+    float Duty_Cycle = 0.0;
+
+    // Check to see if we have gone past the index point
+    if(Position < Lower & LastTiltPosition > Upper) {       // We have gone over the index point in 1 direction
+        Velocity += OneTurn;
+    } else if(Position > Upper & LastTiltPosition < Lower) {// We have gone over the index point in the other direction
+        Velocity -= OneTurn;
+    }  
+    LastTiltPosition = Position;                            // Update new position from next time
+
+    TiltVelocityPID.setProcessValue(Velocity);              // Pass the Velocity onto the PID loop
+    Duty_Cycle = TiltVelocityPID.compute();
+
+    if(Duty_Cycle < 0) {
+        Tilt_Motor_Direction = 0;
+        Tilt_Motor_PWM = 1 - (Duty_Cycle * -1.0);
+    } else {
+        Tilt_Motor_Direction = 1;
+        Tilt_Motor_PWM = 1 - Duty_Cycle;
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UpdateCamera.cpp	Thu Apr 02 07:35:39 2015 +0000
@@ -0,0 +1,70 @@
+#include "mbed.h"
+#include "rtos.h"
+
+#define AUTO 1
+#define MANUAL 0
+
+extern Serial Camera;
+extern bool Mode;
+
+void UpdateCamera (float ZoomDemand, float FocusDemand)
+{
+    static signed int LastZoom = 0;
+    static signed int LastFocus = 0;
+
+    // The ZoomDemand value passed to this function is a raw read of the AnalogIn object
+    ZoomDemand -= 0.5;                          // Shift the raw value to the centre-tap
+    ZoomDemand *= -14;                          // Scale to get in the -7 to +7 range
+    int Zoom = (int)ZoomDemand;                 // Cast to an int
+
+    // Do the same thing for Focus
+    FocusDemand *= 0x7000;                      // Scale to the range of 0 to 28672
+    FocusDemand += 0x0800;                      // Add a shift of 2048 to get to 2048 to 30720
+    int Focus = (int)FocusDemand & 0xFFC0;      // Knock off the last 6 bits of noise!
+
+    // See if we need to move the Camera Zoom Position
+    if(Zoom != LastZoom) {
+
+        // First calculate the new Zoom Setting
+        if (Zoom > 0) {
+            // Send the tele command
+            Zoom += 0x20;
+        } else if(Zoom < 0) {
+            // Send the wide command
+            Zoom *= -1;
+            Zoom += 0x30;
+        }
+        LastZoom = Zoom;                        // Update the last know Focus Demand for next time
+
+        // Send first 4 characters (always the same)
+        Camera.putc(0x81);
+        Camera.putc(0x01);
+        Camera.putc(0x04);
+        Camera.putc(0x07);
+        Camera.putc(Zoom);
+        Camera.putc(0xFF);
+    }
+
+    // Now see if we need to move the Camera Focus Position
+    if(Mode == MANUAL && Focus != LastFocus) {
+        Camera.putc(0x81);                      // Camera
+        Camera.putc(0x01);
+        Camera.putc(0x04);
+        Camera.putc(0x48);                      // Direct focus cmd
+        Camera.putc((Focus & 0xF000)>>12);      // p variable
+        Camera.putc((Focus & 0x0F00)>>8);       // q variable
+        Camera.putc((Focus & 0x00F0)>>4);       // r variable
+        Camera.putc(Focus & 0x000F);            // s variable
+        Camera.putc(0xFF);
+
+        LastFocus = Focus;                      // Update the last know Focus Demand for next time
+    }
+
+    // Return the current Zoom position    
+    Camera.putc(0x81);                  // Address byte from host to camera - 0x81
+    Camera.putc(0x09);                  // Zoom position inquiry - 8x 09 04 47 ff
+    Camera.putc(0x04);
+    Camera.putc(0x47);
+    Camera.putc(0xFF);                  // Terminator byte - all 1s
+    
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/iC_MU.lib	Thu Apr 02 07:35:39 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/teams/Vitec-Group/code/iC_MU/#ae562ccce5bd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Apr 02 07:35:39 2015 +0000
@@ -0,0 +1,237 @@
+#include "mbed.h"
+#include "iC_MU.h"
+#include "rtos.h"
+#include "Classic_PID.h"
+
+#define _Kp 0.18            // Kp.Freq product
+#define _Ki 0.006           // Ki.Freq product
+
+Serial pc(USBTX,USBRX);
+
+// iC-MU Encoder Objects
+iC_MU tilt_ic_mu(p5,p6,p7,p8);
+iC_MU TiltPos(p5,p6,p7,p11);
+iC_MU pan_ic_mu(p5,p6,p7,p12);
+iC_MU PanPos(p5,p6,p7,p13);
+/*
+// Tilt Motor
+PwmOut Tilt_Motor_PWM(p27);                     // Purple wire
+DigitalOut Tilt_Motor_Direction(p28);           // Yellow wire
+
+// Pan Motor
+PwmOut Pan_Motor_PWM(p25);                      // Purple wire
+DigitalOut Pan_Motor_Direction(p26);            // Yellow wire
+*/
+// Tilt Motor
+PwmOut Tilt_Motor_PWM(p23);                     // Purple wire
+DigitalOut Tilt_Motor_Direction(p24);           // Yellow wire
+
+// Pan Motor
+PwmOut Pan_Motor_PWM(p21);                      // Purple wire
+DigitalOut Pan_Motor_Direction(p22);            // Yellow wire
+
+// Joystick stuff
+AnalogIn Pan_Joystick(p16);
+AnalogIn Tilt_Joystick(p17);
+AnalogIn Zoom_Joystick(p18);
+AnalogIn Focus_Pot(p19);            // The top Pot (Pot 1)
+
+// Camera Stuff
+Serial Camera(p9,p10);
+InterruptIn Switch(p14);
+DigitalOut led1(LED1),led2(LED2), led3(LED3), led4(LED4);
+#define AUTO 1
+#define MANUAL 0
+
+/* Kp = 0.00018, Ki = 0.000006, Kd = 0.0, 0.0001 */
+Classic_PID PanVelocityPID(0.00018, 0.000006, 0.0, 0.0001);     //Kp, ki, kd, kvelff
+Classic_PID TiltVelocityPID(0.00018, 0.000006, 0.0, 0.0001);    //Kp, ki, kd, kvelff
+
+// Globals
+int ZoomPos = 0;
+bool AutofocusFlag = true;
+bool ManualfocusFlag = false;
+bool Mode = AUTO;
+bool joystick = true;
+
+extern int LastPanPosition;
+extern int LastTiltPosition;
+float Pan_JoyStickDem = 0.0;
+float Tilt_JoyStickDem = 0.0;
+
+void PanVelocityLoop(void const *args);
+void TiltVelocityLoop(void const *args);
+//int ServiceKeyboard();
+void UpdateCamera(float, float);
+/*
+// Code for interrupt on Rx from Camera
+extern "C" void MyUart3Handler(void)
+{
+    static int index = 0;
+    static char msg[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+
+    // Read the byte and put it into the next available element of the array
+    msg[index] = Camera.getc();
+
+    // Check to see if that is the end of the message
+    if(msg[index] == 0xFF) {
+        // Check to see if the response is zoom data i.e. 7 bytes long and starts with 0x90, 0x50...
+        if(index == 6 && msg[0] == 0x90 && msg[1] == 0x50) {
+            ZoomPos = (msg[2] & 0x0F) << 12;
+            ZoomPos += (msg[3] & 0x0F) << 8;
+            ZoomPos += (msg[4] & 0x0F) << 4;
+            ZoomPos += (msg[5] & 0x0F);
+        }
+        index = 0;
+    } else {
+        index++;
+    }
+}
+
+void isr_Switch(void)
+{
+    wait_ms(1);                 // Wait 1ms and check if the switch is still pressed
+    if (Switch) {
+        wait_ms(1);             // Wait another 1ms and double check the switch
+        if (Switch) {
+            Mode = !Mode;
+            if(Mode == AUTO) {
+                AutofocusFlag = true;
+            } else {
+                ManualfocusFlag = true;
+            }
+        }
+    }
+}*/
+
+void Anti_Lock(void const *args)
+{
+    Pan_Motor_Direction = !Pan_Motor_Direction.read();      // Toggle motor direction to overcome lock protection
+    Tilt_Motor_Direction = !Tilt_Motor_Direction.read();
+    wait_us(10);
+    Pan_Motor_Direction = !Pan_Motor_Direction.read();
+    Tilt_Motor_Direction = !Tilt_Motor_Direction.read();
+}
+
+int main()
+{
+    // Increase the Camera baud rate
+    Camera.baud(38400);
+/*    
+    // Set up the Camera Rx Interrupt & enable it
+    NVIC_SetVector(UART3_IRQn, (uint32_t)MyUart3Handler);
+    NVIC_EnableIRQ(UART3_IRQn);
+    LPC_UART3->IER = 0x01;
+
+    // Set up the switch to toggle autofocus
+    Switch.mode(PullDown);                  //Set the internal pull down resistor
+    Switch.rise(&isr_Switch);               //ISR for the switch
+    led4 = 1;                               // We start in autofocus mode
+    led1 = 1;                               // Turn all other LEDs off
+    led2 = 1;
+    led3 = 0;
+*/    
+    // Set up the Pan motor
+    Pan_Motor_PWM.period_us(50);                // Set PWM to 20 kHz
+    Pan_Motor_PWM = 1;                          // Start with motor static
+
+    // Set up the Tilt motor
+    Tilt_Motor_PWM.period_us(50);               // Set PWM to 20 kHz
+    Tilt_Motor_PWM = 1;                         // Start with motor static
+
+    // Initalise Pan Velocity loop RtosTimer thread
+    RtosTimer PanVelocityLoop_timer(PanVelocityLoop, osTimerPeriodic);
+    PanVelocityLoop_timer.start(1);             // Run at 1kHz
+
+    // Initalise Tilt Velocity loop RtosTimer thread
+    RtosTimer TiltVelocityLoop_timer(TiltVelocityLoop, osTimerPeriodic);
+    TiltVelocityLoop_timer.start(1);            // Run at 1kHz
+
+    // Initalise Pan PID Loop
+    PanVelocityPID.setProcessLimits(1.0, -1.0);
+    PanVelocityPID.setSetPoint(0);
+    LastPanPosition = pan_ic_mu.ReadPOSITION() >> 1;
+
+    // Initalise Tilt PID Loop
+    TiltVelocityPID.setProcessLimits(1.0, -1.0);
+    TiltVelocityPID.setSetPoint(0);
+    LastTiltPosition = tilt_ic_mu.ReadPOSITION() >> 1;
+
+    // Initalise Anti-Lock RtosTimer thread
+    RtosTimer Anti_Lock_timer(Anti_Lock, osTimerPeriodic);
+    Anti_Lock_timer.start(1000);                // Run at 1Hz
+
+    while(1) {
+        Thread::wait(100);
+        // Update the Zoom and Focus Demands
+        UpdateCamera(Zoom_Joystick.read(),Focus_Pot.read());
+        Thread::wait(100);
+        
+        if(joystick) {
+           Pan_JoyStickDem = Pan_Joystick.read() - 0.5;
+           Tilt_JoyStickDem = Tilt_Joystick.read() - 0.5;
+           Pan_JoyStickDem *= 80;
+           Tilt_JoyStickDem *= -80;
+           // Square the demand for pan joystick profile
+           if(Pan_JoyStickDem > 0) {
+               Pan_JoyStickDem = Pan_JoyStickDem * Pan_JoyStickDem;
+           } else {
+               Pan_JoyStickDem = Pan_JoyStickDem * Pan_JoyStickDem * -1;
+           }
+           // Square the demand for tilt joystick profile
+           if(Tilt_JoyStickDem > 0) {
+               Tilt_JoyStickDem = Tilt_JoyStickDem * Tilt_JoyStickDem;
+           } else {
+               Tilt_JoyStickDem = Tilt_JoyStickDem * Tilt_JoyStickDem * -1;
+           }
+           PanVelocityPID.setSetPoint((int)Pan_JoyStickDem);            // Read the joystick and apply the gain
+           TiltVelocityPID.setSetPoint((int)Tilt_JoyStickDem);          // Read the joystick and apply the gain
+       }
+/*
+        if(AutofocusFlag) {
+            // Turn on the autofocus
+            led4 = 1;                               // Turn the LED on to show we are in auto-focus mode
+            Camera.putc(0x81);                      // Camera
+            Camera.putc(0x01);                      // Turn on auto-focus cmd
+            Camera.putc(0x04);
+            Camera.putc(0x38);
+            Camera.putc(0x02);
+            Camera.putc(0xFF);                      // Terminator
+            AutofocusFlag = false;
+            Mode = AUTO;
+        }
+        if(ManualfocusFlag) {
+            // Turn on Manual focus
+            led4 = 0;                               // Turn the LED off to show we are in manual-focus mode
+            Camera.putc(0x81);                      // Camera
+            Camera.putc(0x01);                      // Turn on manual-focus cmd
+            Camera.putc(0x04);
+            Camera.putc(0x38);
+            Camera.putc(0x03);
+            Camera.putc(0xFF);                      // Terminator
+            ManualfocusFlag = false;
+            Mode = MANUAL;
+        }*/
+    }
+}
+
+ /*   
+    // Increase the serial baud rate
+    // pc.baud(921600);
+
+    while(1) {
+        Thread::wait(100);
+
+       if(pc.readable()) {
+           ServiceKeyboard();
+       }
+       if(Capture) {
+           // Print to terminal the current motor encoder positions
+           pc.printf("\n\r %d %d ",pan_ic_mu.ReadPOSITION(),tilt_ic_mu.ReadPOSITION());
+       }
+       
+       if(Demand) {
+           pc.printf("\n\r %0.3f ",PanVelocityPID.getSetPoint());
+       }
+   }
+}*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos.lib	Thu Apr 02 07:35:39 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-rtos/#d3d0e710b443
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Thu Apr 02 07:35:39 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/e188a91d3eaa
\ No newline at end of file