motion primitives
Dependencies: mbed
Fork of Motion_Primitive_Test by
MotionTest.cpp
- Committer:
- JordanWisdom
- Date:
- 2016-03-18
- Revision:
- 2:0f93881225d2
- Parent:
- 1:d523415c7b53
File content as of revision 2:0f93881225d2:
// EE4333 Robotics Lab 3 // Library Imports //#include "InterruptIn.h" //#include "rtos.h" #include "mbed.h" #include "Serial.h" #include "stdio.h" //Function Declarations void DE0_Init(int); void L_MotorInit(void); void R_MotorInit(void); signed int InputLeft(void); signed int InputRight(void); void ControlThread(void); int SaturateAdd(int x, int y); float SaturateLimit(float x, float limit); signed int SignExtend(signed int x); char GUI(); void Settings(char x); // ******************************************************************** // GLOBAL VARIABLE DECLARATIONS // ******************************************************************** signed int R_setpoint; // Desired Angular Speed ( rad/sec ) signed int L_setpoint; signed int R_setpoint_m; // Desired Angular Speed ( m/sec ) signed int L_setpoint_m; float R_e; // Velocity Error float R_u; // Control Signal float L_e; float L_u; int L_integrator; // Left Integrator State int R_integrator; signed int dPositionLeft; // DE0 Register 0 signed int dPositionRight; int dTimeLeft; // DE0 Register 1 int dTimeRight; float Circ = 0; float tTot = 0; //Motion Primitive Variables signed int Arc; float Radius = 0; float VelDes = 0; float tcalc = 0; float O_setpoint; //Inner Wheel Speed float I_setpoint; //Outer Wheel Speed float L = 5.5*2.54/100; //Distance between wheel contacts ; //Distance between wheels (in meters) float pi = 3.141259; // ********************************************************************* // PROCESSES AND THREADS // ********************************************************************* // ********************************************************************* // PIN DECLARATIONS // ********************************************************************* // Digital I/O Pins DigitalOut led1(LED1); // Thread Indicators DigitalOut led2(LED2); // DigitalOut led3(LED3); // DigitalOut led4(LED4); // DigitalOut DirL(p29); // Direction of Left Motor DigitalOut DirR(p30); // Direction of Right Motor // SPI Related Digital I/O Pins DigitalOut SpiReset(p11); DigitalOut IoReset(p12); //PWM PwmOut PwmL(p22); PwmOut PwmR(p21); //Serial Serial pc(USBTX, USBRX); // tx and rx for PC serial channel via USB cable Serial Bluetooth(p9,p10); // Pins tx(p9) , rx(p10) for bluetooth serial channel //SPI SPI DE0(p5,p6,p7); //Pin 5 is MOSI, Pin 6 MISO, Pin 7 SCLK //Interrupts Ticker ControlInterrupt; // Internal Interrupt to trigger Control Thread // *************************************************** // DE0 Init // *************************************************** void DE0_Init(int SpiControlWord){ int mode = 1; int bits = 16; DE0.format(bits,mode); // Verify Peripheral ID // Generates single square pulse to reset DE0 IO IoReset = 0; IoReset = 1; IoReset = 0; // Generates single square pulse to reset DE0 SPI SpiReset = 0; SpiReset = 1; SpiReset = 0; // Writes to DE0 Control Register int ID = DE0.write(SpiControlWord); // SPI Control Word specifies SPI settings if(ID == 23){ // DE0 ID 23 (0x0017) Bluetooth.printf("\n\r >> DE0 Initialized.\n\r");} else{ Bluetooth.printf("\n\r >> Failed to initialize DE0 board.\n\r");} } // *************************************************** // Left Motor Initialization // *************************************************** // Pwm Pin Left Motor : p21 // Direction Pin Left Motor : p29 void L_MotorInit(void){ DirL = 1; // Defaults to 1 // Direction bit logic output // 0 : Backwards ( Reverse ) // 1 : Forwards ( Advance ) PwmL.period_us(100); PwmL.write(0); } // *************************************************** // Right Motor Initialization // *************************************************** // Pwm Pin Right Motor : p22 // Direction Pin Right Motor : p30 void R_MotorInit(void){ DirR = 0; // Defaults to 0. // Direction bit logic output // 0 : Forwards ( Advance ) // 1 : Backwards ( Reverse ) PwmR.period_us(100); PwmR.write(0); } /// *************************************************** // Control Thread // *************************************************** void ControlThread(void){ // Read Incremental Position from DE0 QEI int dummy = 0x0000; // Pushes dummy information which DE0 ignores, store return from QEI register dPositionLeft = SignExtend(DE0.write(dummy)); dTimeLeft = DE0.write(dummy); dPositionRight = SignExtend(DE0.write(dummy)); dTimeRight = DE0.write(dummy); // Computer Angular Speed and Angular Speed Error signed int AngularSpeedLeft = (123*dPositionLeft)/dTimeLeft; signed int AngularSpeedRight = (123*dPositionRight)/dTimeRight; //CHANGED FOR OUTER AND INNER WHEELS L_e = O_setpoint - AngularSpeedLeft; R_e = I_setpoint - AngularSpeedRight; float Kp_L = 2.5; float Ki_L = 0.010; float Kp_R = 2.5; float Ki_R = 0.010; // **** MODIFICATIONS FOR MOTION PRIMITIVE ARE HERE **** // In order to determine theta relative to any given position, we can just use Theta = Arc Length/Radius // Radius R is determined by the user // Arc Length is determined from an integration of average velocity dP/dt, which is tracked by the DE0 board //Arc Length (meters) variable - We have speed and time outputs already so we can use those values to calculate average arc of V //Arc = (AngularSpeedLeft*dTimeLeft+AngularSpeedRight*dTimeRight)*0.05093/2; //constant of 0.05093 derived in another function using wheel radii // Saturate Inegrators if necessary if(abs(SaturateLimit((Kp_L*L_e+Ki_L*L_integrator)/35,1))<1){ L_integrator = L_integrator +L_e;} else{ L_integrator = L_integrator; } if(abs(SaturateLimit((Kp_R*R_e+Ki_R*R_integrator)/35,1))<1){ R_integrator = R_integrator +R_e;} else{ R_integrator = R_integrator; } L_u = SaturateLimit( (Kp_L*L_e+Ki_L*L_integrator),1); R_u = SaturateLimit( (Kp_R*R_e+Ki_R*R_integrator),1); if(L_u <=0) DirL = 0; else DirL = 1; if(R_u <=0) DirR = 1; else DirR = 0; PwmL.write(abs(L_u)); PwmR.write(abs(R_u)); } /// *************************************************** // SaturateAdd // *************************************************** signed int SaturateAdd(signed int x, signed int y){ signed int z = x + y; if( (x>0) && (y>0)&& (z<=0) ){ z = 0x7FFFFFFF;} else if( (x<0)&&(y<0)&&(z>=0) ){ z = 0x80000000;} return z; } /// *************************************************** // SaturateLimit // *************************************************** float SaturateLimit(float x, float limit){ if (x > limit){ return limit; } else if(x < -limit){ return(-limit); } else{ return x;} } /// *************************************************** // Sign Extend // *************************************************** signed int SignExtend(int x){ if(x&0x00008000){ x = x|0xFFFF0000; } return x; } char GUI(){ char x; pc.printf("\n\r (C)ircle or (L)ine? >>"); pc.scanf("%c", &x); return x; } void Settings(char x){ char z; if(x == 'c' || x == 'C') { pc.printf("\n\rCircle Radius? (m)"); pc.scanf("%f", &Radius); pc.printf("\n\rDesired Speed? (m)"); pc.scanf("%f", &VelDes); pc.printf("\n\r Desired Direction? (L) or (R)"); pc.scanf("%c",&z); float Circ = 2*pi*Radius; float tTot = Circ/VelDes; if(z == 'l' || z == 'L') { I_setpoint = (Radius+L/2)*2*pi/((2*2.54/100)*tTot); if(I_setpoint>35) { I_setpoint = 35; pc.printf("Setpoint limit exceeded. Capping outer wheel speed at %2.2f m/s", O_setpoint*0.05094); } O_setpoint = I_setpoint*(Radius-L/2)/(Radius+L/2); } else { O_setpoint = (Radius+L/2)*2*pi/((2*2.54/100)*tTot); if(O_setpoint>35) { O_setpoint = 35; pc.printf("Setpoint limit exceeded. Capping outer wheel speed at %2.2f m/s", O_setpoint*0.05094); } I_setpoint = (Radius-L/2)*2*pi/((2*2.54/100)*tTot); } } else { pc.printf("\n\r Desired Speed? (m) >>"); pc.scanf("%f", &VelDes); O_setpoint = VelDes/0.05094; if(O_setpoint>35) { O_setpoint = 35; pc.printf("\n\r Speed maximum exceeded. Capping outer wheel speed at %f m/s", O_setpoint*0.05094); } I_setpoint = O_setpoint; } return; } // ============================================================================================================== // ============================================================================================================== // ********************************************************************* // MAIN FUNCTION // ********************************************************************* int main(){ // Initialization DE0_Init(0x8004); L_MotorInit(); R_MotorInit(); L_integrator = 0; R_integrator = 0; ControlInterrupt.attach(&ControlThread, 0.0005); //Motion Primitives Initialization Arc = 0; // Arc Length (start at 0) Settings(GUI()); float SpeedActual; unsigned int VLeft,VRight; // Display Global Variables to Console while(1){ VLeft = 123*(dPositionLeft/dTimeLeft); VRight = 123*(dPositionRight/dTimeRight); SpeedActual = (VLeft+VRight)/2; pc.printf("\n\r||VLeft: %2.2f ||VRight: %2.2f ||Radius: %2.2f",VLeft,VRight,SpeedActual); wait(1); } }