As used for motor testing May / June 2016
Dependencies: iC_MU mbed-rtos mbed
Fork of SweptSine by
Revision 3:463edcfc09c5, committed 2016-06-08
- Comitter:
- acodd
- Date:
- Wed Jun 08 13:56:25 2016 +0000
- Parent:
- 2:be3b6a72f823
- Commit message:
- As used for scoping motors May / June 2016
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Axis_Control.cpp Wed Jun 08 13:56:25 2016 +0000 @@ -0,0 +1,403 @@ +#include "mbed.h" +#include "iC_MU.h" +#include "rtos.h" +#include "MyAxis.h" + +extern iC_MU pan_Motor, PanPos; +extern PwmOut Pan_Motor_PWM; + +extern iC_MU tilt_Motor, TiltPos; +extern PwmOut Tilt_Motor_PWM; + +extern DigitalOut Pan_Motor_Direction; +extern DigitalOut Tilt_Motor_Direction; + +extern Serial pc; + +extern float Pan_count; + +// Deal with profiling and scoping (generic) +bool scoping; +int scope_duration = 1000; +int scope_time = 0; +float amplitude; +float a; +float Hz; +extern float start_Hz; +extern float stop_Hz; +extern float run_time; +float jogaccel_time = 2000; +float jogaccel = 1; +float dwell = 1000; +float bits = 19; +int OneTurnCts = pow(2, bits); //491520 +int MyLower = pow(2,(bits-4)); +int MyUpper = OneTurnCts - MyLower; +int skip = 0; +int primed = 0; + + +// Motor Generics +float c; +float m; +float Duty_Cycle = 0; +float Motor_Direction; +float Motor_PWM; +float DeadBand = 0.012; +int Motor_wrap = 4194304; + + +void PanAxisInitialise() +{ + //MyAxis Pan; + Pan.Number = 1; + Pan.jog = 3; + Pan.sysjogdir = 1; + Pan.sinusoidrun = 0; + Pan.scoping = 0; + Pan.setramp = 0; + Pan.setramp_x = 0; + Pan.moveme = 0; + Pan.ramp = 0.05; + Pan.run_count = 0; + Pan.ratio = 115; //This is 115 on original breadboard, -113 on a prototype MS5 + Pan.Motor_scale = 11100; //15728; //(based on 1800RPM, 2^19 encoder and 0.001s loop) + Pan.c_moving = 20; + Pan.c_stationary = 2; + Pan.Jog_1 = 0; + Pan.Jog_2 = 60; + Pan.Kp = 0.060; + Pan.Kp_Sys = 0.000; + Pan.Kff = 1; + Pan.Kff_Sys = 1; + Pan.Feed_Forward = 0; + Pan.Prev_Motor_final = 0; + Pan.Motor_Vel = 0; + Pan.Motor_position = 0; + Pan.dojog = 0; + Pan.sysdojog = 0; + Pan.jogdir = 1; + Pan.sysjogdir = 1; + Pan.start_MotPos = 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 + Pan.Motor_Inst_Pos = pan_Motor.ReadPOSITION(); + Pan.MotorLast_Inst_Pos = Pan.Motor_Inst_Pos; + + Pan.Motor_position = 0; + Pan.MotorDemandPos = 0; + Pan.System_position = PanPos.ReadPOSITION(); + Pan.SysDemandPos = Pan.System_position; + Pan.SysDemand_Prev = Pan.SysDemandPos; + Pan.Sys_follow_error = Pan.SysDemandPos - Pan.System_position; + //pc.printf("\n\r %d,%f,%f,%f,%f",scope_time,Axis.Motor_position,Axis.System_position,Axis.SysDemandPos,Axis.Sys_follow_error); +} + +void TiltAxisInitialise() +{ + //MyAxis Pan; + Tilt.Number = 2; + Tilt.jog = 3; + Tilt.sysjogdir = 1; + Tilt.sinusoidrun = 0; + Tilt.scoping = 0; + Tilt.setramp = 0; + Tilt.setramp_x = 0; + Tilt.moveme = 0; + Tilt.ramp = 0.05; + Tilt.run_count = 0; + Tilt.ratio = -115; // This is -115 on original prototype unit, -113 on a prototype MS5) + Tilt.Motor_scale = 11100; //15728; //(based on 1800RPM, 2^19 encoder and 0.001s loop) + Tilt.c_moving = 20; + Tilt.c_stationary = 2; + Tilt.Jog_1 = 0; + Tilt.Jog_2 = 60; + Tilt.Kp = 0.06; + Tilt.Kp_Sys = 0.0005; + Tilt.Kff = 1; + Tilt.Kff_Sys = 1; + Tilt.Feed_Forward = 0; + Tilt.Prev_Motor_final = 0; + Tilt.Motor_Vel = 0; + Tilt.Motor_position = 0; + Tilt.dojog = 0; + Tilt.sysdojog = 0; + Tilt.jogdir = 1; + Tilt.sysjogdir = 1; + Tilt.start_MotPos = 0; + + + // Set up the Tilt motor + Tilt_Motor_PWM.period_us(50); // Set PWM to 20 kHz + Tilt_Motor_PWM = 1; // Start with motor static + Tilt.Motor_Inst_Pos = tilt_Motor.ReadPOSITION(); + Tilt.MotorLast_Inst_Pos = Tilt.Motor_Inst_Pos; + + Tilt.Motor_position = 0; + Tilt.MotorDemandPos = 0; + Tilt.System_position = TiltPos.ReadPOSITION(); + Tilt.SysDemandPos = Tilt.System_position; + Tilt.SysDemand_Prev = Tilt.SysDemandPos; + Tilt.Sys_follow_error = Tilt.SysDemandPos - Tilt.System_position; + //pc.printf("\n\r %d,%f,%f,%f,%f",scope_time,Axis.Motor_position,Axis.System_position,Axis.SysDemandPos,Axis.Sys_follow_error); +} + +void UpdatePanFeedback() +{ + Pan.MotorLast_Inst_Pos = Pan.Motor_Inst_Pos; + Pan.Motor_Inst_Pos = pan_Motor.ReadPOSITION(); + + Pan.Motor_Vel = (Pan.Motor_Inst_Pos - Pan.MotorLast_Inst_Pos); + + // Check to see if we have gone past the index point + if( (Pan.Motor_Inst_Pos < MyLower) && (Pan.MotorLast_Inst_Pos > MyUpper) ) { // We have gone over the index point in 1 direction + Pan.Motor_Vel += OneTurnCts; + } else if( (Pan.Motor_Inst_Pos > MyUpper) && (Pan.MotorLast_Inst_Pos < MyLower) ) { // We have gone over the index point in the other direction + Pan.Motor_Vel -= OneTurnCts; + } + + Pan.Motor_position = Pan.Motor_position + Pan.Motor_Vel; + + Pan.System_position_prev = Pan.System_position; + Pan.System_position = PanPos.ReadPOSITION(); + + Pan.SysActualVel = Pan.System_position - Pan.System_position_prev; + +} +void UpdateTiltFeedback() +{ + Tilt.MotorLast_Inst_Pos = Tilt.Motor_Inst_Pos; + Tilt.Motor_Inst_Pos = tilt_Motor.ReadPOSITION(); + + Tilt.Motor_Vel = (Tilt.Motor_Inst_Pos - Tilt.MotorLast_Inst_Pos); + + // Check to see if we have gone past the index point + if( (Tilt.Motor_Inst_Pos < MyLower) && (Tilt.MotorLast_Inst_Pos > MyUpper) ) { // We have gone over the index point in 1 direction + Tilt.Motor_Vel += OneTurnCts; + } else if( (Tilt.Motor_Inst_Pos > MyUpper) && (Tilt.MotorLast_Inst_Pos < MyLower) ) { // We have gone over the index point in the other direction + Tilt.Motor_Vel -= OneTurnCts; + } + + Tilt.Motor_position = Tilt.Motor_position + Tilt.Motor_Vel; + + // Tilt.System_position_prev = Tilt.System_position; + Tilt.System_position = TiltPos.ReadPOSITION(); + + // Tilt.SysActualVel = Tilt.System_position - Tilt.System_position_prev; + +} + +void AxisControlLoop(MyAxis& Axis) +{ + if (Axis.Number == 1) { + UpdatePanFeedback(); + } else if (Axis.Number == 2) { + UpdateTiltFeedback(); + } + + + // *********************************************************** + // Sinusoid test + + if ((Axis.sinusoidrun) && (Axis.jog > 0)) { + //pc.printf("\n\r%d,%d,%f,%f",run_count,(Motor_Inst_Pos-262144),outprint,(b*1000)); + //Time (ms),Motor,System,SysDemandPos,frequency (Hz),Demand") + pc.printf("\n\r%f,%f,%f,%f,%f",Axis.run_count,(Axis.Motor_position - Axis.start_MotPos),((Axis.System_position - Axis.start_SysPos)* Axis.ratio),(Hz*100),((Axis.SysDemandPos - Axis.start_SysPos) * Axis.ratio)); + + if(Axis.run_count < (run_time * 1000)) { + // demandpos = 262144 + (amplitude * sin((a*run_count*run_count)+(b*run_count))); + Hz = (start_Hz + (a * Axis.run_count)); // This is the demand frequency + //SysDemandPos = SysDemandPos + (amplitude * sin(2 * 3.14159 * Hz * run_count / 1000)); + Axis.SysDemandPos = Axis.start_SysPos + (amplitude * sin(2 * 3.14159 * Hz * Axis.run_count / 1000)); + // PanVelocityPID.setSetPoint(demandpos); + Axis.run_count++; // Inc run_count + } else { + Axis.sinusoidrun = 0; // Stop the test + Axis.run_count = 0; + } + } + + // *********************************************************** + // Calculate the effective ratio on the fly + + if ((Axis.calcmyratio) && (fabs(Axis.SysActualVel) > 0)) { + + Axis.dynamicratio = fabs((Axis.Motor_Vel) / (Axis.SysActualVel)); + + + } + + // *********************************************************** + // Go ahead and move at a set speed + + if (Axis.moveme) { + Axis.SysDemandPos = Axis.SysDemandPos + (Axis.jog * Axis.sysjogdir); + } + + // *********************************************************** + // Create set ramps to follow + // sysjog is System speed demand in counts/ms at the System encoder (output) + if (Axis.setramp) { + if (Axis.run_count_jog < jogaccel_time) { + if (primed) { + scoping = true; + primed = false; + } + Axis.sysjogdir = 1; + Axis.sysdojog = Axis.sysdojog + Axis.ramp; + Axis.run_count_jog++; + Axis.SysDemandPos = Axis.SysDemandPos + Axis.sysdojog; + Axis.SysDemandPos = Axis.SysDemandPos * Axis.sysjogdir; + } else if ((Axis.run_count_jog >= jogaccel_time) && (Axis.run_count_jog < (jogaccel_time + dwell))) { + Axis.sysdojog = Axis.jog; + Axis.run_count_jog++; + Axis.SysDemandPos = Axis.SysDemandPos + (Axis.sysdojog * Axis.sysjogdir); + } else if ((Axis.run_count_jog >= (jogaccel_time + dwell)) && (Axis.run_count_jog < ((2 * jogaccel_time) + dwell))) { + Axis.sysdojog = Axis.sysdojog - Axis.ramp; + Axis.run_count_jog++; + Axis.SysDemandPos = Axis.SysDemandPos + (Axis.sysdojog * Axis.sysjogdir); + } else if ((Axis.run_count_jog >= ((2 * jogaccel_time) + dwell)) && (Axis.run_count_jog < ((3 * jogaccel_time) + dwell))) { + Axis.sysdojog = Axis.sysdojog + Axis.ramp; + Axis.run_count_jog++; + Axis.sysjogdir = -1; + Axis.SysDemandPos = Axis.SysDemandPos + (Axis.sysdojog * Axis.sysjogdir); + } else if ((Axis.run_count_jog >= ((3* jogaccel_time) + dwell)) && (Axis.run_count_jog < ((3* jogaccel_time) + dwell + dwell))) { + Axis.sysdojog = 0; + Axis.run_count_jog++; + } else if (Axis.run_count_jog >= ((3* jogaccel_time) + dwell + dwell)) { + Axis.setramp = false; + Axis.run_count_jog = 0; + Axis.sysjogdir = 1; + scoping = false; + } + } + + if (Axis.setramp_x) { + if (Axis.run_count_jog < jogaccel_time) { + if (primed) { + scoping = true; + primed = false; + } + Axis.sysdojog = Axis.sysdojog + Axis.ramp; + Axis.run_count_jog++; + Axis.SysDemandPos = Axis.SysDemandPos + (Axis.sysdojog * Axis.sysjogdir); + } else if ((Axis.run_count_jog >= jogaccel_time) && (Axis.run_count_jog < (jogaccel_time + dwell))) { + Axis.sysdojog = Axis.jog; + Axis.run_count_jog++; + Axis.SysDemandPos = Axis.SysDemandPos + (Axis.sysdojog * Axis.sysjogdir); + } else if ((Axis.run_count_jog >= (jogaccel_time + dwell)) && (Axis.run_count_jog < ((2 * jogaccel_time) + dwell))) { + Axis.sysdojog = Axis.sysdojog - Axis.ramp; + Axis.run_count_jog++; + Axis.SysDemandPos = Axis.SysDemandPos + (Axis.sysdojog * Axis.sysjogdir); + } else if ((Axis.run_count_jog >= ((2 * jogaccel_time) + dwell)) && (Axis.run_count_jog < ((2 * jogaccel_time) + dwell + dwell))) { + Axis.sysdojog = 0; + Axis.run_count_jog++; + } else if (Axis.run_count_jog >= ((2* jogaccel_time) + dwell + dwell)) { + Axis.setramp_x = false; + Axis.run_count_jog = 0; + scoping = false; + } + } + + + // ********************************************************** + // Generate perfect velocity demand for the System: + Axis.SysProfilerVel = Axis.SysDemandPos - Axis.SysDemand_Prev; + Axis.SysDemand_Prev = Axis.SysDemandPos; + + // ********************************************************** + // Apply proportional gain to the System Velocity demand if sufficient + Axis.Sys_follow_error = Axis.System_position - Axis.SysDemandPos; + Axis.SysDerivedVel = Axis.SysProfilerVel - (Axis.Sys_follow_error * Axis.Kp_Sys); + + // ^ LOAD SIDE + // ************************************************* + // MOTOR CONTROL LOOP + // ************************************************* + // V MOTOR SIDE + + // Apply the system demand to the motor via the gearbox ratio: + Axis.dojog = Axis.SysDerivedVel * Axis.ratio; + + //Derive a motor postion demand + Axis.MotorDemandPos = Axis.MotorDemandPos + Axis.dojog; + + if (Axis.Motor_position <= -Motor_wrap) { + // Motor is moving to wrap in a negative direction so bulk values to the mid point of the encoder + Axis.Motor_position = Axis.Motor_position + (Motor_wrap); + Axis.MotorDemandPos = Axis.MotorDemandPos + (Motor_wrap); + //pc.printf("Wrap neg"); + } else if (Axis.Motor_position >= Motor_wrap) { + // Motor is moving to wrap in a positive direction so bulk values back towards the mid point + Axis.Motor_position = Axis.Motor_position - (Motor_wrap); + Axis.MotorDemandPos = Axis.MotorDemandPos - (Motor_wrap); + //pc.printf("Wrap pos"); + } + + // ********************************************************* + // Apply proportional position loop gain + Axis.follow_error = Axis.MotorDemandPos - Axis.Motor_position; + Axis.Motor_final = (Axis.Kp * Axis.follow_error); + + // ********************************************************* + // Apply feed forward profiling: + // Gain Schedule according to system demand - this prevent stationary oscillation + if (fabs(Axis.SysProfilerVel) > 0) { + c = Axis.c_moving; + } else { + c = Axis.c_stationary; + } + m = (Axis.Jog_2 - c)/Axis.Jog_2; + // Calculate the feed forward value + if ((fabs(Axis.dojog) > (Axis.Jog_1 + 0)) && (fabs(Axis.dojog) <= Axis.Jog_2)) { + Axis.Feed_Forward = ((m*fabs(Axis.dojog)) + c); + if (Axis.dojog <= 0) { + Axis.Feed_Forward = -Axis.Feed_Forward; + } + } else if (fabs(Axis.dojog) > Axis.Jog_2) { + Axis.Feed_Forward = (Axis.Kff * Axis.dojog); + } else { + Axis.Feed_Forward = 0; + } + // Add the feedforward term to the demand already calculated: + Axis.Motor_final = Axis.Motor_final + Axis.Feed_Forward; + + // ***************************************************** + // NOW PREPARE AND SEND DEMAND TO THE MOTOR + // Apply scale factor from user units to motor duty cycle. + Duty_Cycle = Axis.Motor_final / Axis.Motor_scale; + + if(Duty_Cycle < 0) { + Motor_Direction = 1; + Motor_PWM = 1 - ((Duty_Cycle - DeadBand) * -1.0); + } else { + Motor_Direction = 0; + Motor_PWM = 1 - Duty_Cycle - DeadBand; + } + + // Send demand to the (correct) motor: + if (Axis.Number == 1) { + Pan_Motor_Direction = Motor_Direction; + Pan_Motor_PWM = Motor_PWM; + } else if (Axis.Number == 2) { + Tilt_Motor_Direction = Motor_Direction; + Tilt_Motor_PWM = Motor_PWM; + } + +// *************************************************** +// CHOOSE VALUES AND SCOPE THEM + if ((scoping) && (Axis.Number == 2)) { + if (scope_time < 1) { + // pc.printf("\n\r \n\rTime,Motor_position,follow_error,Sys_follow_error,dojog,SysProfilerVel,sysdojog,Feed_Forward"); + pc.printf("\n\r \n\rscope_time,Motor Error,Motor Virtual,Motor Position,System speed,Hall"); + } + pc.printf("\n\r %d,%f,%f,%f,%f,%f",scope_time,Pan.follow_error, (Pan.follow_error / Pan.ratio),Pan.Motor_position, Pan.sysdojog, Pan_count); + scope_time = scope_time + 1; + } + + + +} \ No newline at end of file
--- a/Classic_PID.lib Tue Mar 22 15:35:01 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://developer.mbed.org/teams/Vitec-Group/code/Classic_PID/#972fa3842c17
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyAxis.cpp Wed Jun 08 13:56:25 2016 +0000 @@ -0,0 +1,5 @@ +#include "MyAxis.h" + + +MyAxis Pan; +MyAxis Tilt; \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyAxis.h Wed Jun 08 13:56:25 2016 +0000 @@ -0,0 +1,55 @@ +//#ifndef MYAXIS_H +#define MYAXIS_H + +// Axis Specific structure +struct MyAxis { + int Number; + float jog; + int sysjogdir; + bool sinusoidrun; + bool scoping; + bool calcmyratio; + float dynamicratio; + bool setramp; + bool setramp_x; + bool moveme; + double ramp; + int run_count_jog; + float run_count; + float System_position; + float System_position_prev; + double Sys_follow_error; + double SysDemandPos; + double SysDemand; + double SysProfilerVel; + double SysDerivedVel; + double SysActualVel; + double SysDemand_Prev; + float start_SysPos; + double MotorDemand_DerivedVel; + float ratio; + float Motor_scale; //15728; //(based on 1800RPM, 2^19 encoder and 0.001s loop) + double Motor_final; + float c_moving; + float c_stationary; + float Jog_1; + float Jog_2; + float Kp; + float Kp_Sys; + float Kff; + float Kff_Sys; + double follow_error; + float Feed_Forward; + float Prev_Motor_final; + int Motor_Inst_Pos; + double MotorDemandPos; + int MotorLast_Inst_Pos; + float Motor_Vel; + float Motor_position; + float dojog; + float sysdojog; + int jogdir; + float start_MotPos; +}; +extern MyAxis Pan; +extern MyAxis Tilt;
--- a/PanVelocityLoop.cpp Tue Mar 22 15:35:01 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -#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 icMu, icMu_Output; -extern PwmOut Pan_Motor_PWM; -extern DigitalOut Pan_Motor_Direction; -extern Classic_PID PanVelocityPID; -extern Serial pc; - -extern bool running; -extern float amplitude; -extern float a; -extern float b; - -int LasticMuPosition = 0; -int run_count = 0; - -void PanVelocityLoop(void const *args) -{ - float Duty_Cycle = 0.0; - - // Find the icMu data - int icMuPosition = icMu.ReadPOSITION(); // Read the current position from the iC-MU - PanVelocityPID.setProcessValue(icMuPosition); // Pass the Position onto the PID loop - - //int icMuPosition = icMu.ReadPOSITION() >> (19 - bits); // Read the current position from the iC-MU and bitshift to reduce noise - //int icMuVelocity = icMuPosition - LasticMuPosition; // Calculate change in position (i.e. Velocity) - - if(running) { - pc.printf("\n\r%d %d %d",run_count,icMuPosition,icMu_Output.ReadPOSITION()); - - if(run_count < 5000) { - PanVelocityPID.setSetPoint(262144 + (amplitude * sin((a*run_count*run_count)+(b*run_count)))); - run_count++; // Inc run_count - } else { - running = 0; // Stop the test - //PanVelocityPID.setSetPoint(0); - } - } - /* - // Check to see if the icMu has gone past the index point - if(icMuPosition < Lower & LasticMuPosition > Upper) { // The icMu has gone over the index point in 1 direction - icMuVelocity += OneTurn; - } else if(icMuPosition > Upper & LasticMuPosition < Lower) { // The icMu has gone over the index point in the other direction - icMuVelocity -= OneTurn; - } - - LasticMuPosition = icMuPosition; // Update new position from next time - - // Set the process value - PanVelocityPID.setProcessValue(icMuVelocity); // Pass the Velocity onto the PID loop - */ - - Duty_Cycle = PanVelocityPID.compute_ff(); - - if(Duty_Cycle < 0) { - Pan_Motor_Direction = 1; - Pan_Motor_PWM = 1 - (Duty_Cycle * -1.0); - } else { - Pan_Motor_Direction = 0; - Pan_Motor_PWM = 1 - Duty_Cycle; - } -} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Pan_Feedback.cpp Wed Jun 08 13:56:25 2016 +0000 @@ -0,0 +1,36 @@ +#include "mbed.h" +#include "rtos.h" + +float Pan_count = 1000; + +InterruptIn pan_pulser(p30); // Pulse counter for Pan axis in this case 10 counts per rev. NOTE!! this has to be 3.3V, + +void func_fall(void) +{ + // pc.printf("fall.\n\r"); + //Pan_count = Pan_count -1000; + if (Pan_count > 0) { + Pan_count = 0; + } else { + Pan_count = 1000; + } +} +void func_rise(void) +{ + //pc.printf("rise.\n\r"); + //Pan_count = Pan_count +1000; + if (Pan_count > 0) { + Pan_count = 0; + } else { + Pan_count = 1000; + } +} + +void Pan_Counter(void const *args) +{ + pan_pulser.fall(&func_fall); + pan_pulser.rise(&func_rise); +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ServiceKeyboard.cpp Wed Jun 08 13:56:25 2016 +0000 @@ -0,0 +1,349 @@ +#include "mbed.h" +#include "rtos.h" +#include "MyAxis.h" + + +extern Serial pc; +extern float DeadBand; +extern bool scoping; +extern int scope_duration; +extern int scope_time; +extern bool sinusoid; +extern bool ratiocalc; +extern float jogaccel_time; +extern float jogaccel; +extern int pos_enc_start; +extern int run_count_jog; +extern int primed; +float temp; + + +// Returns the new set point entered via the keyboard +int ServiceKeyboard () +{ + int key; // The keypress by the user + int value = 0; // The variable to return + + key = pc.getc(); // Read the intial keypress + + switch (key) { +// List keypresses used: + case 'q': + // To move up and down: 8, 2: To move left and right 4,6. To start stop both: 5: + pc.printf("\n\r Left, Right, Up Down: 4,6,8,2. \n\r Start & Stop both: 5 \n\r Toggle all directions = d \n\r"); + pc.printf("\n\r Scope = s \n\r Run Test sinusoid = t \n\r Run Ratio Calculator = r \n\r Set Motor Kp = g \n\r Set Sys Kp_Sys = h \n\r Fetch Gain = f \n\r Set Kff_Sys = k \n\r Prime Start Scope = p \n\r Set Kff = 2 \n\r Set Gearbox Ratio = 1 \n\r"); + pc.printf(" Set Stationary c value = c \n\r Set Moving c value = b \n\r Set Jog_2 value = 3 \n\r \n\r \n\r Jog Speed PAN,TILT = j,m \n\r Set Jog Acceleration = a \n\r Cycle to hard Stop = z \n\r Fade = x \n\r"); + break; + +// Turn on Scope Tool: + case 's': + if (!scoping) { + scope_time = 0; + scoping = true; + } else { + scoping = false; + } + break; +// Turn on Ratio Calculator: + case 'r': + if (!ratiocalc) { + ratiocalc = true; + pc.printf("\n\r Running Ratio Calculator"); + } else { + Tilt.calcmyratio = false; + Pan.calcmyratio = false; + } + break; +// We are going to jog Tilt up + case '8': + Tilt.sysjogdir = -1; + if (Tilt.moveme) { + //pc.printf("\n\r Moving stop"); + Tilt.moveme = false; + } else { + //pc.printf("\n\r Moving Start"); + Tilt.moveme = true; + } + break; +// We are going to jog Tilt down + case '2': + Tilt.sysjogdir = 1; + if (Tilt.moveme) { + //pc.printf("\n\r Moving stop"); + Tilt.moveme = false; + } else { + //pc.printf("\n\r Moving Start"); + Tilt.moveme = true; + } + break; +// We are going to jog Tilt up + case '4': + Pan.sysjogdir = -1; + if (Pan.moveme) { + //pc.printf("\n\r Moving stop"); + Pan.moveme = false; + } else { + //pc.printf("\n\r Moving Start"); + Pan.moveme = true; + } + break; +// We are going to jog Tilt down + case '6': + Pan.sysjogdir = 1; + if (Pan.moveme) { + //pc.printf("\n\r Moving stop"); + Pan.moveme = false; + } else { + //pc.printf("\n\r Moving Start"); + Pan.moveme = true; + } + break; +// We are going to jog everything + case '5': + if (Pan.moveme) { + //pc.printf("\n\r Moving stop"); + Pan.moveme = false; + } else { + //pc.printf("\n\r Moving Start"); + Pan.moveme = true; + } + if (Tilt.moveme) { + //pc.printf("\n\r Moving stop"); + Tilt.moveme = false; + } else { + //pc.printf("\n\r Moving Start"); + Tilt.moveme = true; + } + break; +// We are going to toggle all directions + case 'd': + Pan.sysjogdir = -Pan.sysjogdir; + Tilt.sysjogdir = -Tilt.sysjogdir; + break; + +// Turn on Potentiometer control: + case 't': + if (!sinusoid) { + pc.printf("\n\r Running sinusoid test"); + sinusoid = true; + } else { + sinusoid = false; + } + break; +// We are going to set the Motor gain + case 'g': + pc.printf("\n\r Enter a new Motor Kp gain x 1000: "); + //key = pc.getc(); + 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); + Pan.Kp = value; + Pan.Kp = Pan.Kp / 1000; + Tilt.Kp = Pan.Kp; + //PanVelocityPID.setKp(Kp/1000); + pc.printf("\n\r"); + break; +// We are going to set the System gain + case 'h': + pc.printf("\n\r Enter a new System Sys_Kp gain x 10000: "); + //key = pc.getc(); + 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); + Pan.Kp_Sys = value; + Pan.Kp_Sys = Pan.Kp_Sys / 10000; + Tilt.Kp_Sys = Pan.Kp_Sys; + //PanVelocityPID.setKp(Kp/1000); + pc.printf("\n\r"); + break; +// We are going to confirm what the gain is + case 'f': + //Kp = PanVelocityPID.getKp(); + pc.printf("\n\r Kp = %f, Kff = %f, Kp_Sys = %f, Kff_Sys = %f, Ratio = %f, c_stationary = %f, c_moving = %f, Jog_2 = %f \n\r", Pan.Kp,Pan.Kff,Pan.Kp_Sys,Pan.Kff_Sys,Pan.ratio,Pan.c_stationary, Pan.c_moving, Pan.Jog_2); + break; + +// We are going to set the Jog_2 Value: + case '3': + pc.printf("\n\r Enter a new Jog_2 value: "); + //key = pc.getc(); + 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); + Pan.Jog_2 = value; + pc.printf("\n\r"); + break; +// We are going to set the new threshold: + case '1': + pc.printf("\n\r Enter a new gearbox ratio: "); + //key = pc.getc(); + 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); + Pan.ratio = value; + pc.printf("\n\r"); + break; +// We are going to set the Kff gain + case 'w': + pc.printf("\n\r Enter a new Kff gain x 100: "); + //key = pc.getc(); + 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); + Pan.Kff = value; + Pan.Kff = Pan.Kff / 100; + pc.printf("\n\r"); + break; +// We are going to set the dead band for the Motor PWM + case 'k': + pc.printf("\n\r Enter a new Kff_Sys x 100: "); + //key = pc.getc(); + 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); + temp = value; + Pan.Kff_Sys = temp / 100; + pc.printf("\n\r"); + break; +// We are going to set a stationary c value + case 'c': + pc.printf("\n\r Enter a new stationary c value: "); + //key = pc.getc(); + 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); + Pan.c_stationary = value; + pc.printf("\n\r"); + break; +// We are going to set a moving b value + case 'b': + pc.printf("\n\r Enter a new moving c value: "); + //key = pc.getc(); + 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); + Pan.c_moving = value; + pc.printf("\n\r"); + break; +// Set a jog speed + case 'j': + pc.printf("\n\r Set Jog PAN speed (Deg/s) x100 "); + //key = pc.getc(); + 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); + Pan.jog = value; + Pan.jog = (Pan.jog * 0.0145); + pc.printf("\n\r"); + break; +// Set a jog speed + case 'm': + pc.printf("\n\r Set Jog TILT speed (Deg/s) x100 "); + //key = pc.getc(); + 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); + Tilt.jog = value; + Tilt.jog = (Tilt.jog * 0.0145); + pc.printf("\n\r"); + break; +// Set the jog function to cycle to a stop + case 'z': + pc.printf("\n\r Set to ramp to stop \n\r"); + Pan.ramp = Pan.jog / jogaccel_time; + Pan.run_count_jog = 0; + scope_time = 0; + Pan.setramp = true; + break; +// Set a Fade like move + case 'x': + pc.printf("\n\r Set to Fade like move \n\r"); + Pan.ramp = Pan.jog / jogaccel_time; + Pan.run_count_jog = 0; + scope_time = 0; + Pan.setramp_x = true; + + Tilt.ramp = Tilt.jog / jogaccel_time; + Tilt.run_count_jog = 0; + scope_time = 0; + Tilt.setramp_x = true; + break; +// Set a jog acceleration + case 'a': + pc.printf("\n\r Set ramp jogaccel_time, (ms) "); + //key = pc.getc(); + 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); + temp = value; + jogaccel_time = temp; + //ramp = ramp / 1000; + pc.printf("\n\r"); + break; +// Prime the scope tool + case 'p': + pc.printf("\n\r Prime the scope tool \n\r"); + primed = true; + break; + } + return(1); +} + + + + +
--- a/main.cpp Tue Mar 22 15:35:01 2016 +0000 +++ b/main.cpp Wed Jun 08 13:56:25 2016 +0000 @@ -1,85 +1,134 @@ #include "mbed.h" #include "iC_MU.h" #include "rtos.h" -#include "Classic_PID.h" +#include "MyAxis.h" // iC-MU Encoder Objects -iC_MU icMu(p5,p6,p7,p8); -iC_MU icMu_Output(p5,p6,p7,p11); +iC_MU tilt_Motor(p5,p6,p7,p8); +iC_MU TiltPos(p5,p6,p7,p11); +iC_MU pan_Motor(p5,p6,p7,p12); +iC_MU PanPos(p5,p6,p7,p13); +// 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 -/* Kp = 0.00018, Ki = 0.000006, Kd = 0.0, 0.0001 */ -//Classic_PID PanVelocityPID(0.00018, 0.000006, 0.0, 0.0); //Kp, ki, kd, kvelff -Classic_PID PanVelocityPID(0.000006, 0.0000001, 0.0, 0.0); //Kp, ki, kd, kvelff - // Serial objects Serial pc (USBTX,USBRX); -// Global Variables -float run_time = 5.0; +int ServiceKeyboard(); + + +// Global Variables for sinusoidrun +float run_time = 10.0; float start_Hz = 1.0, stop_Hz = 2.0; -float amplitude; -bool running = 0; -float w1; -float w2; -float a; -float b; +extern float amplitude; +bool sinusoid = 0; +extern float a; +extern float Hz; + +// Global variables for auto gearbox calculator +bool ratiocalc = 0; + // External variables extern int LasticMuPosition; // Functions -void PanVelocityLoop(void const *args); +void PanAxisInitialise(); +void TiltAxisInitialise(); +void AxisControlLoop(MyAxis& Axis); +void Pan_Counter(void const *args); + +void RunLoop(void const *args) +{ + AxisControlLoop(Pan); + AxisControlLoop(Tilt); +} int main() { - // Set up the Pan motor - Pan_Motor_PWM.period_us(50); // Set PWM to 20 kHz - Pan_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 Pan PID Loop - PanVelocityPID.setProcessLimits(1.0, -1.0); - PanVelocityPID.setSetPoint(262144); // Set the motor to 2^18 - //PanVelocityPID.setSetPoint(0); - //LasticMuPosition = icMu.ReadPOSITION() >> 1; + //Startme(); + pc.baud(921600); + pc.printf("\n\r AH-10 Motor Scope Tool \n\r"); + pc.printf("\n\r Press q for menu \n\r"); + PanAxisInitialise(); + TiltAxisInitialise(); + RtosTimer RunLoop_timer(RunLoop, osTimerPeriodic); + RunLoop_timer.start(1); // Run at 1kHz - - // Increase terminal speed - pc.baud(921600); + + // Initalise Pan counter RtosTimer thread + RtosTimer Pan_Counter_timer(Pan_Counter, osTimerPeriodic); + Pan_Counter_timer.start(1); - // Prompt the user to enter the test parameters - pc.printf("\n\r Enter Start frequency (Hz): "); - pc.scanf("%f", &start_Hz); - pc.printf("%f",start_Hz); - - pc.printf("\n\r Enter Stop frequency (Hz): "); - pc.scanf("%f", &stop_Hz); - pc.printf("%f",stop_Hz); - - pc.printf("\n\r Enter Amplitude (encoder counts): "); - pc.scanf("%f", &litude); - pc.printf("%f",amplitude); - - pc.printf("\n\n\r Press any key to start test..."); - pc.getc(); - - w1 = start_Hz * 3.14159 * 2; - w2 = stop_Hz * 3.14159 * 2; - a = (w2 - w1) / (2 * run_time * 1000000); - b = w1 / 1000; - - // Set the test running - running = 1; while(1) { - ; + + if(pc.readable()) { + ServiceKeyboard(); + } + + if (sinusoid) { + sinusoid = false; + + // Prompt the user to enter the test parameters + pc.printf("\n\r Enter Start frequency (Hz): "); + pc.scanf("%f", &start_Hz); + pc.printf("%f",start_Hz); + + pc.printf("\n\r Enter Stop frequency (Hz): "); + pc.scanf("%f", &stop_Hz); + pc.printf("%f",stop_Hz); + + pc.printf("\n\r Enter Amplitude (encoder counts): "); + pc.scanf("%f", &litude); + pc.printf("%f",amplitude); + + pc.printf("\n\r Enter Time (s): "); + pc.scanf("%f", &run_time); + pc.printf("%f",run_time); + + pc.printf("\n\n\r Press any key to start test..."); + pc.getc(); + + a = (stop_Hz - start_Hz) / (run_time * 1000); // This is the incrementor + pc.printf("\n\n\n\r ********************************************* \n\n\n\r *************************************************"); + // pc.printf("\n\n\r Time (ms),input,output,frequency (Hz)"); + pc.printf("\n\n\r Time (ms),Motor,System,frequency (Hz x 100),Demand"); + + Pan.start_SysPos = Pan.System_position; + Pan.start_MotPos = Pan.Motor_position; + + Tilt.start_SysPos = Tilt.System_position; + Tilt.start_MotPos = Tilt.Motor_position; + + // Set the test running# + if (Pan.jog > 0){ + Pan.sinusoidrun = 1; + } + if (Tilt.jog > 0) { + Tilt.sinusoidrun = 1; + } + } + + if (ratiocalc) { + ratiocalc = false; + + Pan.start_SysPos = Pan.System_position; + Pan.start_MotPos = Pan.Motor_position; + + Pan.calcmyratio = true; + + Tilt.start_SysPos = Tilt.System_position; + Tilt.start_MotPos = Tilt.Motor_position; + + Tilt.calcmyratio = true; + } } }