MRD Lab / SpindleBot_1_5b

Dependencies:   MX12 ServoRingBuffer mbed-src

Fork of SpindleBot by MRD Lab

Committer:
labmrd
Date:
Mon May 11 21:39:45 2015 +0000
Revision:
8:cef07a8bdc42
Parent:
7:b4b95e5f0fce
Child:
9:f26a91863e3a
The criteria for grasping was changed to trigger off of the master as opposed to the slave.  The calibration runs but seems to read high. FIX THIS!

Who changed what in which revision?

UserRevisionLine numberNew contents of line
labmrd 2:dfeadd6c651c 1 #define USE_DYNAMIXELS
labmrd 2:dfeadd6c651c 2 //#define USE_BLUETOOTH
labmrd 2:dfeadd6c651c 3 #define USE_SD_CARD
labmrd 5:72e92c721cd5 4 #define ROD_IS_RIGHT
labmrd 2:dfeadd6c651c 5
labmrd 2:dfeadd6c651c 6 // We have different modes for different things
labmrd 2:dfeadd6c651c 7 #define MODE_MANUAL 1
labmrd 2:dfeadd6c651c 8 #define MODE_AUTOMATIC 2
labmrd 2:dfeadd6c651c 9 #define MODE_IDLE 3
labmrd 2:dfeadd6c651c 10 #define MODE_NULL 0
labmrd 2:dfeadd6c651c 11
labmrd 2:dfeadd6c651c 12 // We always want to know if we are closing or opening
labmrd 2:dfeadd6c651c 13 #define DIRECTION_CLOSING 1
labmrd 2:dfeadd6c651c 14 #define DIRECTION_OPENING 2
labmrd 2:dfeadd6c651c 15 #define DIRECTION_SLACK_WATER 3
labmrd 2:dfeadd6c651c 16 #define DIRECTION_NULL 0
labmrd 2:dfeadd6c651c 17
labmrd 2:dfeadd6c651c 18 // General includes
mbed_official 0:8a555873b7d3 19 #include "mbed.h"
labmrd 2:dfeadd6c651c 20 #include "ServoRingBuffer.h"
labmrd 2:dfeadd6c651c 21 #include "ram_test.h"
labmrd 2:dfeadd6c651c 22 #include "Serial_Receive.h"
labmrd 5:72e92c721cd5 23 #include "data_set.h"
labmrd 2:dfeadd6c651c 24 #include <string>
labmrd 2:dfeadd6c651c 25
labmrd 2:dfeadd6c651c 26 // Specific to Dynamixels
labmrd 2:dfeadd6c651c 27 #ifdef USE_DYNAMIXELS
labmrd 4:e44ac08027bd 28 #include "AD7730.h"
labmrd 2:dfeadd6c651c 29 #endif
labmrd 2:dfeadd6c651c 30
labmrd 2:dfeadd6c651c 31 // Specific to SD Card
labmrd 2:dfeadd6c651c 32 #ifdef USE_SD_CARD
labmrd 2:dfeadd6c651c 33 #include "SDFileSystem.h"
labmrd 2:dfeadd6c651c 34 #endif
labmrd 2:dfeadd6c651c 35
labmrd 2:dfeadd6c651c 36 // Everyone should know pi...
labmrd 2:dfeadd6c651c 37 #ifndef M_PI
labmrd 2:dfeadd6c651c 38 #define M_PI 3.14159265358979323846 /* pi */
labmrd 2:dfeadd6c651c 39 #endif
labmrd 2:dfeadd6c651c 40 #ifndef M_PI_2
labmrd 2:dfeadd6c651c 41 #define M_PI_2 1.57079632679489661923 /* pi/2 */
labmrd 2:dfeadd6c651c 42 #endif
labmrd 2:dfeadd6c651c 43
labmrd 4:e44ac08027bd 44 // Create enum for the Jaw state (Closing, hold, opening)
labmrd 4:e44ac08027bd 45 enum jaw_state{
labmrd 4:e44ac08027bd 46 STATE_CLOSING=0,
labmrd 4:e44ac08027bd 47 STATE_CLOSE_HOLD=1,
labmrd 4:e44ac08027bd 48 STATE_OPENING=2,
labmrd 4:e44ac08027bd 49 STATE_OPEN_HOLD=3
labmrd 4:e44ac08027bd 50 };
labmrd 2:dfeadd6c651c 51
labmrd 2:dfeadd6c651c 52
labmrd 2:dfeadd6c651c 53 // Define pins and interrupts
labmrd 2:dfeadd6c651c 54 Ticker potISR; //Define a recurring timer interrupt
labmrd 2:dfeadd6c651c 55 DigitalOut led1(LED1); //Led 1 for debugging purposes
labmrd 2:dfeadd6c651c 56 DigitalOut led2(LED2); //Led 2 for debugging purposes
labmrd 2:dfeadd6c651c 57 DigitalOut led3(LED3); //Led 3 for debugging purposes
labmrd 5:72e92c721cd5 58 DigitalOut led4(LED4); //Led 4 for debugging purposes
labmrd 2:dfeadd6c651c 59 DigitalOut triggerOut(p11);
labmrd 2:dfeadd6c651c 60 Serial pc(USBTX, USBRX); //Set up serial connection to pc
labmrd 2:dfeadd6c651c 61 #ifdef USE_BLUETOOTH
labmrd 2:dfeadd6c651c 62 Serial bt(p13,p14); //Set up serial connection to bluetooth adapter
labmrd 2:dfeadd6c651c 63 #endif
labmrd 2:dfeadd6c651c 64
labmrd 5:72e92c721cd5 65
labmrd 5:72e92c721cd5 66 AnalogIn AinLeftForce(p16); //Set up potentiometer on pin 20
labmrd 5:72e92c721cd5 67 AnalogIn AinRightForce(p15); //Set up potentiometer on pin 20
labmrd 2:dfeadd6c651c 68
labmrd 2:dfeadd6c651c 69 #ifdef USE_SD_CARD
labmrd 2:dfeadd6c651c 70 // Attach SD card
labmrd 2:dfeadd6c651c 71 SDFileSystem sd(p5, p6, p7, p8, "sd"); // the pinout on the mbed Cool Components workshop board
labmrd 2:dfeadd6c651c 72 FILE *fp = NULL;
labmrd 2:dfeadd6c651c 73 #define SAMPLES_PER_FILE 10000
labmrd 2:dfeadd6c651c 74 #endif
labmrd 2:dfeadd6c651c 75
labmrd 2:dfeadd6c651c 76 // Dummy variable for debugging
labmrd 2:dfeadd6c651c 77 unsigned int global_count=0;
labmrd 2:dfeadd6c651c 78 float max_percent_full=0;
labmrd 2:dfeadd6c651c 79
labmrd 2:dfeadd6c651c 80 // Define variables for the program
labmrd 2:dfeadd6c651c 81
labmrd 2:dfeadd6c651c 82 char g_tissue_type_name[32];
labmrd 2:dfeadd6c651c 83 float g_frequency;
labmrd 2:dfeadd6c651c 84 int g_max_force;
labmrd 2:dfeadd6c651c 85 int g_num_cycles;
labmrd 2:dfeadd6c651c 86 float g_current_trajectory_time;
labmrd 2:dfeadd6c651c 87 float g_theta;
labmrd 2:dfeadd6c651c 88 float g_theta_last=0;
labmrd 2:dfeadd6c651c 89 unsigned char g_current_mode=MODE_NULL;
labmrd 4:e44ac08027bd 90 jaw_state g_current_direction=STATE_OPEN_HOLD;
labmrd 2:dfeadd6c651c 91 unsigned char g_current_cycle=0;
labmrd 5:72e92c721cd5 92 int g_input_pot_1;
labmrd 5:72e92c721cd5 93 #define NUMBER_OF_TISSUES 2
labmrd 5:72e92c721cd5 94 float g_error_norm[NUMBER_OF_TISSUES];
labmrd 5:72e92c721cd5 95 bool g_we_are_grasping=false;
labmrd 8:cef07a8bdc42 96 #define CALIBRATION_READS 500.0
labmrd 8:cef07a8bdc42 97 float g_calibration_offset = 8600000.0;
labmrd 5:72e92c721cd5 98
labmrd 5:72e92c721cd5 99
labmrd 5:72e92c721cd5 100 ///////////Magic numbers courtesy Rod///////////////
labmrd 5:72e92c721cd5 101 float Phi1[5]={-8.02086003501975e-08,
labmrd 5:72e92c721cd5 102 1.55286905458007e-05,
labmrd 5:72e92c721cd5 103 0.00795344249784777,
labmrd 5:72e92c721cd5 104 8.23733045077119,
labmrd 5:72e92c721cd5 105 -0.00299236282304311};
labmrd 5:72e92c721cd5 106
labmrd 5:72e92c721cd5 107 float Phi2[5]={-1.24436831310503e-08,
labmrd 5:72e92c721cd5 108 1.23673348605010e-05,
labmrd 5:72e92c721cd5 109 0.00652545188345528,
labmrd 5:72e92c721cd5 110 6.75893262890734,
labmrd 5:72e92c721cd5 111 -0.00228098997419065};
labmrd 5:72e92c721cd5 112
labmrd 5:72e92c721cd5 113 float entry_threshold=8.70e6;
labmrd 5:72e92c721cd5 114 float velocty_threshold=-0.01;
labmrd 5:72e92c721cd5 115
labmrd 5:72e92c721cd5 116 float g_thresh_force[NUMBER_OF_TISSUES]={8.80e6,8.75e6};
labmrd 5:72e92c721cd5 117 ///////////Magic numbers courtesy Rod///////////////
labmrd 5:72e92c721cd5 118
labmrd 5:72e92c721cd5 119 int g_command_corrected;
labmrd 5:72e92c721cd5 120
labmrd 8:cef07a8bdc42 121 // These are for load cell initialization of the offset
labmrd 8:cef07a8bdc42 122 long g_loadCellZero = 8600000;
labmrd 8:cef07a8bdc42 123 bool calibrateDone = false;
labmrd 8:cef07a8bdc42 124 long calibrateTotal = 8600;
labmrd 8:cef07a8bdc42 125 int calibCntr = 0;
labmrd 8:cef07a8bdc42 126 int g_loadCellOffset = 100000;
labmrd 8:cef07a8bdc42 127 int g_threshOffset1 = 0.2e6;
labmrd 8:cef07a8bdc42 128 int g_threshOffset2 = 0.15e6;
labmrd 8:cef07a8bdc42 129
labmrd 8:cef07a8bdc42 130
labmrd 5:72e92c721cd5 131 Timer mytimer;
labmrd 2:dfeadd6c651c 132
labmrd 2:dfeadd6c651c 133 // Warning, this buffer is large!
labmrd 2:dfeadd6c651c 134 ServoRingBuffer Buffer;
labmrd 2:dfeadd6c651c 135 spindleData tempSpindleData; //For sending to the buffer
labmrd 5:72e92c721cd5 136 #ifdef ROD_IS_RIGHT
labmrd 5:72e92c721cd5 137 int angle_sum=0;
labmrd 5:72e92c721cd5 138 int angle_count=0;
labmrd 5:72e92c721cd5 139 int angledot_sum=0;
labmrd 5:72e92c721cd5 140 int angledot_count=0;
labmrd 5:72e92c721cd5 141 int last_angle=0;
labmrd 5:72e92c721cd5 142 int angledotdot_sum=0;
labmrd 5:72e92c721cd5 143 int angledotdot_count=0;
labmrd 5:72e92c721cd5 144 int last_angledot=0;
labmrd 5:72e92c721cd5 145 #else
labmrd 5:72e92c721cd5 146 data_set recent_pos(30,"Data","Time (us)","Position (encoder counts)");
labmrd 5:72e92c721cd5 147 float coeffs[4];
labmrd 5:72e92c721cd5 148 bool crunching_data_flag;
labmrd 5:72e92c721cd5 149 #endif
labmrd 5:72e92c721cd5 150
labmrd 5:72e92c721cd5 151 int bits_received;
labmrd 2:dfeadd6c651c 152
labmrd 2:dfeadd6c651c 153 Timer ISRDurationTimer;
labmrd 2:dfeadd6c651c 154 Timer AuxSerialTimer;
labmrd 2:dfeadd6c651c 155 int worst_latency=0;
labmrd 2:dfeadd6c651c 156 int current_latency;
labmrd 2:dfeadd6c651c 157
labmrd 2:dfeadd6c651c 158 #ifdef USE_DYNAMIXELS
labmrd 5:72e92c721cd5 159 Serial cm(p28,p27); //Set up serial connection to OpenCM 9.04
labmrd 5:72e92c721cd5 160 unsigned short left_servo_measured=0;
labmrd 5:72e92c721cd5 161 unsigned short right_servo_measured=0;
labmrd 5:72e92c721cd5 162 char input_buffer[16];
labmrd 5:72e92c721cd5 163 int input_buffer_location=0;
labmrd 5:72e92c721cd5 164
labmrd 5:72e92c721cd5 165 float samplingPeriod = 0.001; //This is the sampling period for the timer interrupt
labmrd 2:dfeadd6c651c 166 #define LEFT_JAW_DYNAMIXEL_ID 3
labmrd 2:dfeadd6c651c 167 #define RIGHT_JAW_DYNAMIXEL_ID 4
labmrd 5:72e92c721cd5 168 // #define CLOSED_SERVO_ANGLE_LEFT 1001 //This is the closed in encoder counts
labmrd 5:72e92c721cd5 169 // #define OPEN_SERVO_ANGLE_LEFT 2663 //This is the open in encoder counts
labmrd 5:72e92c721cd5 170 // #define CLOSED_SERVO_ANGLE_RIGHT 3259 //This is the closed in encoder counts
labmrd 5:72e92c721cd5 171 // #define OPEN_SERVO_ANGLE_RIGHT 1486 //This is the open in encoder counts
labmrd 5:72e92c721cd5 172 #define CLOSED_SERVO_ANGLE_LEFT 1975 //This is the closed in encoder counts
labmrd 5:72e92c721cd5 173 #define OPEN_SERVO_ANGLE_LEFT 2560 //This is the open in encoder counts
labmrd 5:72e92c721cd5 174 #define CLOSED_SERVO_ANGLE_RIGHT 1975 //This is the closed in encoder counts
labmrd 5:72e92c721cd5 175 #define OPEN_SERVO_ANGLE_RIGHT 2560 //This is the open in encoder counts
labmrd 5:72e92c721cd5 176 //AD7730( mosi, miso, sclk, ready, cs)
labmrd 5:72e92c721cd5 177 AD7730 adc(p11, p12, p13, p14, p15);
labmrd 5:72e92c721cd5 178 //AD7730 adc2(p11, p12, p13, p18, p19);
labmrd 2:dfeadd6c651c 179
labmrd 5:72e92c721cd5 180
labmrd 6:b4347c69816a 181 AnalogIn AinJoystickFwdBk(p17); //Set up potentiometer on pin 17
labmrd 6:b4347c69816a 182 AnalogIn AinJoystickLftRt(p16); //Set up potentiometer on pin 16
labmrd 5:72e92c721cd5 183 float JoystickFwdBk_Zero=0.5;
labmrd 5:72e92c721cd5 184 float JoystickLftRt_Zero=0.5;
labmrd 4:e44ac08027bd 185
labmrd 4:e44ac08027bd 186 /// Set these to inputs so that they don't interfere with the serial communication
labmrd 2:dfeadd6c651c 187 DigitalIn nullOut1(p21);
labmrd 2:dfeadd6c651c 188 DigitalIn nullOut2(p22);
labmrd 2:dfeadd6c651c 189 DigitalIn nullOut3(p23);
labmrd 2:dfeadd6c651c 190 DigitalIn nullOut4(p24);
labmrd 5:72e92c721cd5 191 /// This one is in the way of the SMD pads
labmrd 5:72e92c721cd5 192 DigitalIn nullOut5(p20);
labmrd 2:dfeadd6c651c 193 #else
labmrd 2:dfeadd6c651c 194 float samplingPeriod = 0.001; //This is the sampling period for the timer interrupt
labmrd 2:dfeadd6c651c 195 #define SERVO_DEGREE_0 900 //This is the pulse width value for HiTEC-422 in microseconds to turn 0 degrees
labmrd 2:dfeadd6c651c 196 #define SERVO_DEGREE_180 2100 //This is the pulse width value for HiTEC-422 in microseconds to turn 180 degrees
labmrd 2:dfeadd6c651c 197 #define MIN_SERVO_ANGLE 0.0 //This is the minimum servo angle in degrees
labmrd 2:dfeadd6c651c 198 #define MAX_SERVO_ANGLE 180.0 //This is the maximum servo angle in degrees
labmrd 2:dfeadd6c651c 199 #define MIN_SERVO_ANGLE_Da_VINCI 20.0 //This is the minimum servo angle in degrees
labmrd 2:dfeadd6c651c 200 #define MAX_SERVO_ANGLE_Da_VINCI 100.0 //This is the maximum servo angle in degrees
labmrd 2:dfeadd6c651c 201 const float servoConversion = ((SERVO_DEGREE_180-SERVO_DEGREE_0)/(MAX_SERVO_ANGLE - MIN_SERVO_ANGLE))/1000000.0; //This is the interpolation between min and max servo values
labmrd 2:dfeadd6c651c 202 const float servoOffset = SERVO_DEGREE_0/1000000.0; //This is the pulsewidth value (in seconds) that corresponds to 0 degrees (i.e.-the offset)
labmrd 2:dfeadd6c651c 203
labmrd 2:dfeadd6c651c 204 PwmOut myServoLeft(p21); //Set up servo on pin 21
labmrd 2:dfeadd6c651c 205 PwmOut myServoRight(p22); //Set up servo on pin 22
labmrd 2:dfeadd6c651c 206 AnalogIn AinLeftPosition(p20); //Set up potentiometer on pin 20
labmrd 2:dfeadd6c651c 207 AnalogIn AinRightPosition(p19); //Set up potentiometer on pin 20
labmrd 2:dfeadd6c651c 208
labmrd 2:dfeadd6c651c 209
labmrd 2:dfeadd6c651c 210 // Function moveServoTo: Convert a degree value to pulsewidth for Servo
labmrd 2:dfeadd6c651c 211 void moveServoTo(float angle) {
labmrd 2:dfeadd6c651c 212 // Make sure none of the user input falls outside of min and max angle limits
labmrd 2:dfeadd6c651c 213 if( angle < MIN_SERVO_ANGLE){angle = MIN_SERVO_ANGLE;}
labmrd 2:dfeadd6c651c 214 else if(angle > MAX_SERVO_ANGLE){angle = MAX_SERVO_ANGLE;}
labmrd 2:dfeadd6c651c 215 myServoLeft.pulsewidth(servoOffset + servoConversion*(180-angle));
labmrd 2:dfeadd6c651c 216 myServoRight.pulsewidth(servoOffset + servoConversion*(angle));
labmrd 2:dfeadd6c651c 217 }
labmrd 2:dfeadd6c651c 218
labmrd 2:dfeadd6c651c 219 #endif
labmrd 2:dfeadd6c651c 220
labmrd 5:72e92c721cd5 221 void serialInterrupt(char buffer){
labmrd 5:72e92c721cd5 222 input_buffer[input_buffer_location]=buffer;
labmrd 5:72e92c721cd5 223 input_buffer_location++;
labmrd 5:72e92c721cd5 224 bits_received+=8;
labmrd 5:72e92c721cd5 225 //pc.printf("RC:%d\n",buffer);
labmrd 5:72e92c721cd5 226
labmrd 5:72e92c721cd5 227
labmrd 5:72e92c721cd5 228 //Is the packet looking good so far??
labmrd 5:72e92c721cd5 229 if(input_buffer[0]==0xFF){
labmrd 5:72e92c721cd5 230 //Is the packet looking good so far??????
labmrd 5:72e92c721cd5 231 if(input_buffer[1]==0xFF || input_buffer_location ==1){
labmrd 5:72e92c721cd5 232 //Do we have a complete packet??
labmrd 5:72e92c721cd5 233 if(input_buffer_location>=6){ //This is 6 because we already incremented
labmrd 5:72e92c721cd5 234 //We do! Extract the jucy datas
labmrd 5:72e92c721cd5 235 left_servo_measured = ( input_buffer[2] << 8 ) | input_buffer[3];
labmrd 5:72e92c721cd5 236 right_servo_measured = ( input_buffer[4] << 8 ) | input_buffer[5];
labmrd 5:72e92c721cd5 237 //pc.printf("RP:%d,%d\n",left_servo_measured,right_servo_measured);
labmrd 5:72e92c721cd5 238 //Reset the buffer location so we can start over
labmrd 5:72e92c721cd5 239 input_buffer_location=0;
labmrd 5:72e92c721cd5 240 }
labmrd 5:72e92c721cd5 241 }else{
labmrd 5:72e92c721cd5 242 //Something is wrong. We may just not be at the correct location in the packet
labmrd 5:72e92c721cd5 243 //Reset the buffer location so we can start over
labmrd 5:72e92c721cd5 244 input_buffer_location=0;
labmrd 5:72e92c721cd5 245 //printf("Error, Byte 2 not what was expected: 0xFF!=0x%02x\n",input_buffer[1]);
labmrd 5:72e92c721cd5 246 }
labmrd 5:72e92c721cd5 247 }else{
labmrd 5:72e92c721cd5 248 //Something is wrong. We may just not be at the correct location in the packet
labmrd 5:72e92c721cd5 249 //Reset the buffer location so we can start over
labmrd 5:72e92c721cd5 250 input_buffer_location=0;
labmrd 5:72e92c721cd5 251 //printf("Error, Byte 1 not what was expected: 0xFF!=0x%02x\n",input_buffer[0]);
labmrd 5:72e92c721cd5 252 }
labmrd 5:72e92c721cd5 253 }
labmrd 5:72e92c721cd5 254
labmrd 5:72e92c721cd5 255
labmrd 4:e44ac08027bd 256 // Function trapezoidalTrajectory: Function that takes in a time (float in seconds) and outputs a float (0 to 1) that corresponds to a trapezoidal trajectory
labmrd 4:e44ac08027bd 257 float trapezoidalTrajectory(float t, jaw_state &state, unsigned char &cycle_num) {
labmrd 4:e44ac08027bd 258 // Define variables specific to this function
labmrd 4:e44ac08027bd 259 float y_trapezoid = 0.0;
labmrd 4:e44ac08027bd 260 float timeMod;
labmrd 4:e44ac08027bd 261 float modifiedFrequency = g_frequency/2.0;
labmrd 4:e44ac08027bd 262 float period = 1/modifiedFrequency;
labmrd 4:e44ac08027bd 263 cycle_num=t*modifiedFrequency;
labmrd 4:e44ac08027bd 264
labmrd 4:e44ac08027bd 265 // Take the time and mod it with the period to be able to break up each cycle into 4 piecewise sections
labmrd 4:e44ac08027bd 266 timeMod = fmodf(t,period);
labmrd 4:e44ac08027bd 267
labmrd 4:e44ac08027bd 268 //
labmrd 4:e44ac08027bd 269 if (timeMod < period/4.0)
labmrd 4:e44ac08027bd 270 {
labmrd 4:e44ac08027bd 271 y_trapezoid = (-4.0/period)*(timeMod)+1.0;
labmrd 4:e44ac08027bd 272 state = STATE_CLOSING;
labmrd 4:e44ac08027bd 273 }
labmrd 4:e44ac08027bd 274 else if (timeMod >= period/4.0 && timeMod < period/2.0)
labmrd 4:e44ac08027bd 275 {
labmrd 4:e44ac08027bd 276 y_trapezoid = 0.0;
labmrd 4:e44ac08027bd 277 state = STATE_CLOSE_HOLD;
labmrd 4:e44ac08027bd 278 }
labmrd 4:e44ac08027bd 279 else if (timeMod >= period/2.0 && timeMod < 3*period/4.0)
labmrd 4:e44ac08027bd 280 {
labmrd 4:e44ac08027bd 281 y_trapezoid = (4.0/period)*(timeMod)-2;
labmrd 4:e44ac08027bd 282 state = STATE_OPENING;
labmrd 4:e44ac08027bd 283 }
labmrd 4:e44ac08027bd 284 else if (timeMod >= 3*period/4.0)
labmrd 4:e44ac08027bd 285 {
labmrd 4:e44ac08027bd 286 y_trapezoid = 1.0;
labmrd 4:e44ac08027bd 287 state = STATE_OPEN_HOLD;
labmrd 4:e44ac08027bd 288 }
labmrd 4:e44ac08027bd 289
labmrd 4:e44ac08027bd 290 return y_trapezoid;
labmrd 4:e44ac08027bd 291 }
labmrd 4:e44ac08027bd 292
labmrd 4:e44ac08027bd 293 void sinusoidalTrajectory(float t, jaw_state &state, unsigned char &cycle_num) {
labmrd 4:e44ac08027bd 294 //Fill me with SCIENCE!!!
labmrd 4:e44ac08027bd 295 }
labmrd 4:e44ac08027bd 296
labmrd 4:e44ac08027bd 297
labmrd 2:dfeadd6c651c 298 // Function timerISRFunction: Timer ISR function to collect data and write to ring buffer
labmrd 2:dfeadd6c651c 299 void timerISRFunction() {
labmrd 8:cef07a8bdc42 300 if (calibrateDone){
labmrd 8:cef07a8bdc42 301 //led 1 is used as a 'thinking' light, brighter=worse
labmrd 8:cef07a8bdc42 302 led1 = 1;
labmrd 8:cef07a8bdc42 303 led2 = 0;
labmrd 8:cef07a8bdc42 304 triggerOut = 1;
labmrd 2:dfeadd6c651c 305
labmrd 8:cef07a8bdc42 306 ISRDurationTimer.reset();
labmrd 8:cef07a8bdc42 307 ISRDurationTimer.start();
labmrd 8:cef07a8bdc42 308 if(g_current_mode==MODE_AUTOMATIC){
labmrd 8:cef07a8bdc42 309
labmrd 8:cef07a8bdc42 310 // Warning, this calculation is in the ISR and as such is probably slower than we would prefer.
labmrd 8:cef07a8bdc42 311 // @todo The math could certainly be optimized with some precalculated constants. Lookup tables are faster than sin()
labmrd 8:cef07a8bdc42 312 float percent=trapezoidalTrajectory(g_current_trajectory_time,g_current_direction,g_current_cycle);
labmrd 8:cef07a8bdc42 313 g_current_trajectory_time+=samplingPeriod;
labmrd 8:cef07a8bdc42 314
labmrd 8:cef07a8bdc42 315
labmrd 8:cef07a8bdc42 316 //float angle=g_current_trajectory_time*g_frequency*2.0*M_PI-M_PI_2;
labmrd 8:cef07a8bdc42 317 //g_current_direction=(cos(angle)<0);
labmrd 8:cef07a8bdc42 318 //g_current_cycle=(angle+M_PI_2)/(2.0*M_PI);
labmrd 8:cef07a8bdc42 319
labmrd 8:cef07a8bdc42 320
labmrd 8:cef07a8bdc42 321 #ifdef USE_DYNAMIXELS
labmrd 8:cef07a8bdc42 322 //float percent=(sin(angle)+1)/2.0;
labmrd 8:cef07a8bdc42 323 if(adc.isReady()){
labmrd 8:cef07a8bdc42 324 adc.interruptRead();
labmrd 8:cef07a8bdc42 325 }
labmrd 8:cef07a8bdc42 326
labmrd 8:cef07a8bdc42 327 while(cm.readable()){
labmrd 8:cef07a8bdc42 328 led4=1;
labmrd 8:cef07a8bdc42 329 serialInterrupt(cm.getc());
labmrd 8:cef07a8bdc42 330 }
labmrd 8:cef07a8bdc42 331 led4=0;
labmrd 8:cef07a8bdc42 332
labmrd 8:cef07a8bdc42 333 short left_servo =percent*(CLOSED_SERVO_ANGLE_LEFT -OPEN_SERVO_ANGLE_LEFT )+OPEN_SERVO_ANGLE_LEFT ;
labmrd 8:cef07a8bdc42 334 short right_servo=percent*(CLOSED_SERVO_ANGLE_RIGHT-OPEN_SERVO_ANGLE_RIGHT)+OPEN_SERVO_ANGLE_RIGHT;
labmrd 8:cef07a8bdc42 335
labmrd 8:cef07a8bdc42 336 //Send the commanded position to the OpenCM board
labmrd 8:cef07a8bdc42 337 cm.putc(0xFF);
labmrd 8:cef07a8bdc42 338 cm.putc(0xFF);
labmrd 8:cef07a8bdc42 339 cm.putc(left_servo >> 8); //Top 4 bits
labmrd 8:cef07a8bdc42 340 cm.putc(left_servo & 0xFF); //Bottom 8 bits
labmrd 8:cef07a8bdc42 341 cm.putc(right_servo >> 8); //Top 4 bits
labmrd 8:cef07a8bdc42 342 cm.putc(right_servo & 0xFF); //Bottom 8 bits
labmrd 8:cef07a8bdc42 343
labmrd 8:cef07a8bdc42 344 tempSpindleData.myServoData[LEFT_SERVO_INDEX].force = adc.read();
labmrd 8:cef07a8bdc42 345 tempSpindleData.myServoData[LEFT_SERVO_INDEX].pos = left_servo_measured;
labmrd 8:cef07a8bdc42 346 tempSpindleData.myServoData[RIGHT_SERVO_INDEX].force = 0;
labmrd 8:cef07a8bdc42 347 tempSpindleData.myServoData[RIGHT_SERVO_INDEX].pos = right_servo_measured;
labmrd 8:cef07a8bdc42 348 tempSpindleData.direction=g_current_direction;
labmrd 8:cef07a8bdc42 349 tempSpindleData.cycle=g_current_cycle;
labmrd 8:cef07a8bdc42 350 Buffer.write(tempSpindleData);
labmrd 8:cef07a8bdc42 351 #else
labmrd 8:cef07a8bdc42 352 g_theta=(1.0-percent)*(MAX_SERVO_ANGLE_Da_VINCI-MIN_SERVO_ANGLE_Da_VINCI)+MIN_SERVO_ANGLE_Da_VINCI;
labmrd 8:cef07a8bdc42 353 tempSpindleData.myServoData[LEFT_SERVO_INDEX].force = AinLeftForce.read_u16();
labmrd 8:cef07a8bdc42 354 tempSpindleData.myServoData[LEFT_SERVO_INDEX].pos = AinLeftPosition.read_u16();
labmrd 8:cef07a8bdc42 355 tempSpindleData.myServoData[RIGHT_SERVO_INDEX].force = AinRightForce.read_u16();
labmrd 8:cef07a8bdc42 356 tempSpindleData.myServoData[RIGHT_SERVO_INDEX].pos = AinRightPosition.read_u16();
labmrd 8:cef07a8bdc42 357 tempSpindleData.direction=g_current_direction;
labmrd 8:cef07a8bdc42 358 tempSpindleData.cycle=g_current_cycle;
labmrd 8:cef07a8bdc42 359 Buffer.write(tempSpindleData);
labmrd 8:cef07a8bdc42 360
labmrd 8:cef07a8bdc42 361
labmrd 8:cef07a8bdc42 362
labmrd 8:cef07a8bdc42 363 moveServoTo(g_theta); // in degrees, son
labmrd 8:cef07a8bdc42 364 #endif
labmrd 8:cef07a8bdc42 365 }else if(g_current_mode==MODE_MANUAL){
labmrd 8:cef07a8bdc42 366
labmrd 8:cef07a8bdc42 367 g_current_trajectory_time+=samplingPeriod;
labmrd 4:e44ac08027bd 368 if(adc.isReady()){
labmrd 4:e44ac08027bd 369 adc.interruptRead();
labmrd 4:e44ac08027bd 370 }
labmrd 4:e44ac08027bd 371
labmrd 8:cef07a8bdc42 372 int im_tired_of_this_game=0;
labmrd 8:cef07a8bdc42 373 while(cm.readable() && im_tired_of_this_game++<100){
labmrd 5:72e92c721cd5 374 serialInterrupt(cm.getc());
labmrd 5:72e92c721cd5 375 }
labmrd 8:cef07a8bdc42 376
labmrd 8:cef07a8bdc42 377 // float pot_open=0.75;
labmrd 8:cef07a8bdc42 378 // float pot_closed=0.48;
labmrd 8:cef07a8bdc42 379 //
labmrd 8:cef07a8bdc42 380 // float percent=AinJoystickFwdBk.read();
labmrd 8:cef07a8bdc42 381 // percent=(pot_open-percent)/(pot_open-pot_closed);
labmrd 8:cef07a8bdc42 382 // float skew =0;//AinJoystickLftRt.read()-JoystickLftRt_Zero;
labmrd 8:cef07a8bdc42 383 //
labmrd 8:cef07a8bdc42 384 // // The 'pulling' of the trigger corresponds to open/closed
labmrd 8:cef07a8bdc42 385 // short left_servo =percent*(CLOSED_SERVO_ANGLE_LEFT -OPEN_SERVO_ANGLE_LEFT )+OPEN_SERVO_ANGLE_LEFT ;
labmrd 8:cef07a8bdc42 386 // short right_servo=percent*(CLOSED_SERVO_ANGLE_RIGHT-OPEN_SERVO_ANGLE_RIGHT)+OPEN_SERVO_ANGLE_RIGHT;
labmrd 8:cef07a8bdc42 387 //
labmrd 8:cef07a8bdc42 388 // g_input_pot_1=left_servo;
labmrd 8:cef07a8bdc42 389 short left_servo =g_command_corrected;
labmrd 8:cef07a8bdc42 390 short right_servo=g_command_corrected;
labmrd 5:72e92c721cd5 391
labmrd 8:cef07a8bdc42 392 // // The 'skewing' of the trigger corresponds to yawing the jaws left or right, while maintaining open/closed
labmrd 8:cef07a8bdc42 393 // left_servo +=skew*(CLOSED_SERVO_ANGLE_LEFT -OPEN_SERVO_ANGLE_LEFT );
labmrd 8:cef07a8bdc42 394 // right_servo-=skew*(CLOSED_SERVO_ANGLE_RIGHT-OPEN_SERVO_ANGLE_RIGHT);
labmrd 8:cef07a8bdc42 395 //
labmrd 8:cef07a8bdc42 396 // /// Todo: There is undoubtedly a cleaner way to do this.
labmrd 8:cef07a8bdc42 397 // if(OPEN_SERVO_ANGLE_LEFT < CLOSED_SERVO_ANGLE_LEFT && left_servo < OPEN_SERVO_ANGLE_LEFT ){left_servo =OPEN_SERVO_ANGLE_LEFT; }
labmrd 8:cef07a8bdc42 398 // if(OPEN_SERVO_ANGLE_LEFT > CLOSED_SERVO_ANGLE_LEFT && left_servo > OPEN_SERVO_ANGLE_LEFT ){left_servo =OPEN_SERVO_ANGLE_LEFT; }
labmrd 8:cef07a8bdc42 399 // if(OPEN_SERVO_ANGLE_RIGHT < CLOSED_SERVO_ANGLE_RIGHT && right_servo < OPEN_SERVO_ANGLE_RIGHT){right_servo=OPEN_SERVO_ANGLE_RIGHT;}
labmrd 8:cef07a8bdc42 400 // if(OPEN_SERVO_ANGLE_RIGHT > CLOSED_SERVO_ANGLE_RIGHT && right_servo > OPEN_SERVO_ANGLE_RIGHT){right_servo=OPEN_SERVO_ANGLE_RIGHT;}
labmrd 8:cef07a8bdc42 401 //
labmrd 8:cef07a8bdc42 402 // // Just to make sure
labmrd 8:cef07a8bdc42 403 // // left_servo=(left_servo+4096)%4096;
labmrd 8:cef07a8bdc42 404 // if(left_servo < 0){left_servo = 0;}
labmrd 8:cef07a8bdc42 405 // if(left_servo >4095){left_servo =4095;}
labmrd 8:cef07a8bdc42 406 // if(right_servo< 0){right_servo= 0;}
labmrd 8:cef07a8bdc42 407 // if(right_servo>4095){right_servo=4095;}
labmrd 4:e44ac08027bd 408
labmrd 5:72e92c721cd5 409 //Send the commanded position to the OpenCM board
labmrd 5:72e92c721cd5 410 cm.putc(0xFF);
labmrd 5:72e92c721cd5 411 cm.putc(0xFF);
labmrd 5:72e92c721cd5 412 cm.putc(left_servo >> 8); //Top 4 bits
labmrd 5:72e92c721cd5 413 cm.putc(left_servo & 0xFF); //Bottom 8 bits
labmrd 5:72e92c721cd5 414 cm.putc(right_servo >> 8); //Top 4 bits
labmrd 5:72e92c721cd5 415 cm.putc(right_servo & 0xFF); //Bottom 8 bits
labmrd 5:72e92c721cd5 416
labmrd 8:cef07a8bdc42 417 #ifdef ROD_IS_RIGHT
labmrd 8:cef07a8bdc42 418 //Famous Rod's Magical World of Good Ideas Part 1
labmrd 8:cef07a8bdc42 419 int angle=left_servo_measured;
labmrd 8:cef07a8bdc42 420 angle_sum+=angle;
labmrd 8:cef07a8bdc42 421 if(angle_count!=0){
labmrd 8:cef07a8bdc42 422 int angledot=(angle-last_angle);
labmrd 8:cef07a8bdc42 423 angledot_sum+=angledot;
labmrd 8:cef07a8bdc42 424 if(angledot_count!=0){
labmrd 8:cef07a8bdc42 425 int angledotdot=(angledot-last_angledot);
labmrd 8:cef07a8bdc42 426 angledotdot_sum+=angledotdot;
labmrd 8:cef07a8bdc42 427 angledotdot_count++;
labmrd 8:cef07a8bdc42 428 }
labmrd 8:cef07a8bdc42 429 angledot_count++;
labmrd 8:cef07a8bdc42 430 last_angledot=angledot;
labmrd 8:cef07a8bdc42 431 }
labmrd 8:cef07a8bdc42 432 angle_count++;
labmrd 8:cef07a8bdc42 433 last_angle=angle;
labmrd 8:cef07a8bdc42 434 #else
labmrd 8:cef07a8bdc42 435 // John's worse than Rod ideas of terribleness
labmrd 8:cef07a8bdc42 436 if(!crunching_data_flag){ // Only add data if no one is using it
labmrd 8:cef07a8bdc42 437 recent_pos.add_data(left_servo_measured,g_current_trajectory_time);
labmrd 8:cef07a8bdc42 438 }
labmrd 8:cef07a8bdc42 439 #endif
labmrd 8:cef07a8bdc42 440 }
labmrd 2:dfeadd6c651c 441
labmrd 8:cef07a8bdc42 442 //done thinking
labmrd 8:cef07a8bdc42 443 led1 = 0;
labmrd 8:cef07a8bdc42 444 led2 = 1;
labmrd 8:cef07a8bdc42 445 triggerOut = 0;
labmrd 2:dfeadd6c651c 446
labmrd 8:cef07a8bdc42 447 ISRDurationTimer.stop();
labmrd 8:cef07a8bdc42 448 current_latency=ISRDurationTimer.read_us();
labmrd 8:cef07a8bdc42 449 if(current_latency>worst_latency){
labmrd 8:cef07a8bdc42 450 worst_latency=current_latency;
labmrd 8:cef07a8bdc42 451 }
labmrd 2:dfeadd6c651c 452 }
mbed_official 0:8a555873b7d3 453 }
labmrd 2:dfeadd6c651c 454
labmrd 7:b4b95e5f0fce 455 // Calibrate Load Cell Function
labmrd 7:b4b95e5f0fce 456 void calibrateLoadCell() {
labmrd 8:cef07a8bdc42 457 long long loadCellTotal = 0;
labmrd 7:b4b95e5f0fce 458 for(int ii=0;ii<CALIBRATION_READS;ii++){
labmrd 8:cef07a8bdc42 459 loadCellTotal+= adc.read();
labmrd 8:cef07a8bdc42 460 wait_ms(2);
labmrd 7:b4b95e5f0fce 461 //pc.printf("We are calibrating load cells...\n");
labmrd 7:b4b95e5f0fce 462 }
labmrd 7:b4b95e5f0fce 463 g_calibration_offset=loadCellTotal/CALIBRATION_READS;
labmrd 8:cef07a8bdc42 464 //Update values for thresholding based on calibration
labmrd 8:cef07a8bdc42 465 g_thresh_force[0]=g_threshOffset1+g_calibration_offset;
labmrd 8:cef07a8bdc42 466 g_thresh_force[1]=g_threshOffset2+g_calibration_offset;
labmrd 8:cef07a8bdc42 467 calibrateDone = true;
labmrd 7:b4b95e5f0fce 468 }
labmrd 7:b4b95e5f0fce 469
labmrd 2:dfeadd6c651c 470
mbed_official 0:8a555873b7d3 471 int main() {
labmrd 2:dfeadd6c651c 472 // Crazy fast baud rate!
labmrd 5:72e92c721cd5 473 pc.baud(115200);
labmrd 5:72e92c721cd5 474
labmrd 5:72e92c721cd5 475 // For communication with OpenCM 9.04 Board
labmrd 5:72e92c721cd5 476 cm.baud(1000000);
labmrd 2:dfeadd6c651c 477
labmrd 2:dfeadd6c651c 478 #ifdef USE_BLUETOOTH
labmrd 2:dfeadd6c651c 479 bt.baud(9600);
labmrd 2:dfeadd6c651c 480 #endif
labmrd 2:dfeadd6c651c 481
labmrd 2:dfeadd6c651c 482 // Attach ISR routines
labmrd 8:cef07a8bdc42 483 potISR.attach(&timerISRFunction, samplingPeriod); // setup serialPot to call every samplingPeriod
labmrd 8:cef07a8bdc42 484
labmrd 2:dfeadd6c651c 485
labmrd 2:dfeadd6c651c 486 // Some debug info:
labmrd 2:dfeadd6c651c 487 //DisplayRAMBanks();
labmrd 2:dfeadd6c651c 488 //printf ("System clock = %d\r\n", SystemCoreClock);
labmrd 2:dfeadd6c651c 489
labmrd 2:dfeadd6c651c 490 pc.printf("\n\n\n");
labmrd 2:dfeadd6c651c 491 pc.printf("----------------------------------\n");
labmrd 2:dfeadd6c651c 492 pc.printf("| |\n");
labmrd 2:dfeadd6c651c 493 pc.printf("| Welcome to our mbed! |\n");
labmrd 2:dfeadd6c651c 494 pc.printf("| |\n");
labmrd 2:dfeadd6c651c 495 pc.printf("| John and Trevor, Proprietors |\n");
labmrd 2:dfeadd6c651c 496 pc.printf("| |\n");
labmrd 2:dfeadd6c651c 497 pc.printf("----------------------------------\n");
labmrd 2:dfeadd6c651c 498 pc.printf(" ||\n");
labmrd 2:dfeadd6c651c 499 pc.printf(" ||\n");
labmrd 2:dfeadd6c651c 500 pc.printf(" || _\n");
labmrd 2:dfeadd6c651c 501 pc.printf(" || _( )_\n");
labmrd 2:dfeadd6c651c 502 pc.printf(" || (_(#)_)\n");
labmrd 2:dfeadd6c651c 503 pc.printf(" || (_)\\\n");
labmrd 2:dfeadd6c651c 504 pc.printf(" || | __\n");
labmrd 2:dfeadd6c651c 505 pc.printf(" \\ / | || |/_/\n");
labmrd 2:dfeadd6c651c 506 pc.printf(" / | | / / / | || | \\ \\ | / \n");
labmrd 2:dfeadd6c651c 507 pc.printf("/ / \\ \\ / / / || / | / / \\ \\ \n");
labmrd 2:dfeadd6c651c 508 pc.printf("#################################\n");
labmrd 2:dfeadd6c651c 509 pc.printf("#################################\n");
labmrd 2:dfeadd6c651c 510 pc.printf("\n\n");
labmrd 2:dfeadd6c651c 511
labmrd 2:dfeadd6c651c 512 #ifdef USE_DYNAMIXELS
labmrd 4:e44ac08027bd 513 adc.setFilter(256 , false, 1);
labmrd 8:cef07a8bdc42 514 calibrateLoadCell();
labmrd 4:e44ac08027bd 515 adc.start();
labmrd 5:72e92c721cd5 516 JoystickLftRt_Zero=0;
labmrd 5:72e92c721cd5 517 int calib_N=100;
labmrd 5:72e92c721cd5 518 for(int ii=0;ii<calib_N;ii++){JoystickLftRt_Zero+=AinJoystickLftRt.read();}
labmrd 5:72e92c721cd5 519 JoystickLftRt_Zero=JoystickLftRt_Zero/calib_N;
labmrd 5:72e92c721cd5 520 g_current_mode=MODE_MANUAL;
labmrd 2:dfeadd6c651c 521 #else
labmrd 2:dfeadd6c651c 522 // Configure Servo for HiTec 422
labmrd 2:dfeadd6c651c 523 myServoLeft.period_ms(20);
labmrd 2:dfeadd6c651c 524 myServoRight.period_ms(20);
labmrd 2:dfeadd6c651c 525 #endif
labmrd 2:dfeadd6c651c 526
labmrd 8:cef07a8bdc42 527
labmrd 7:b4b95e5f0fce 528
labmrd 2:dfeadd6c651c 529 printf("Setup Complete.\n");
labmrd 2:dfeadd6c651c 530 AuxSerialTimer.start();
labmrd 5:72e92c721cd5 531 mytimer.start();
labmrd 2:dfeadd6c651c 532 while(1)
labmrd 2:dfeadd6c651c 533 {
labmrd 2:dfeadd6c651c 534 // spin in a main loop. serialISR will interrupt it to call serialPot
labmrd 2:dfeadd6c651c 535
labmrd 8:cef07a8bdc42 536
labmrd 8:cef07a8bdc42 537
labmrd 5:72e92c721cd5 538 #ifdef USE_DYNAMIXELS
labmrd 5:72e92c721cd5 539
labmrd 5:72e92c721cd5 540 #endif
labmrd 5:72e92c721cd5 541
labmrd 2:dfeadd6c651c 542 ///This checks for any new serial bytes, and returns true if
labmrd 2:dfeadd6c651c 543 ///we have an entire packet ready. The new packet will live
labmrd 2:dfeadd6c651c 544 ///in newData.
labmrd 2:dfeadd6c651c 545 if(
labmrd 2:dfeadd6c651c 546 #ifdef USE_BLUETOOTH
labmrd 2:dfeadd6c651c 547 receivePacket(bt)
labmrd 2:dfeadd6c651c 548 #else
labmrd 2:dfeadd6c651c 549 receivePacket(pc)
labmrd 2:dfeadd6c651c 550 #endif
labmrd 2:dfeadd6c651c 551 )
labmrd 2:dfeadd6c651c 552 {
labmrd 2:dfeadd6c651c 553 // < Tissue Type (string), Frequency Value (Hz) (int), Force Max (N) (int), # Cycles (in) >
labmrd 2:dfeadd6c651c 554 //<date/tissue/time,2,3,4>
labmrd 2:dfeadd6c651c 555 //g_tissue_type_name=tissue_type_name;
labmrd 2:dfeadd6c651c 556 std::string file_name_in=inString.substr(0, inString.find(","));
labmrd 2:dfeadd6c651c 557 g_frequency=newData[1]/10.0; // Since all we send are ints
labmrd 2:dfeadd6c651c 558 g_max_force=newData[2];
labmrd 2:dfeadd6c651c 559 g_num_cycles=newData[3];
labmrd 2:dfeadd6c651c 560 g_current_trajectory_time=0;
labmrd 4:e44ac08027bd 561 g_current_cycle=0;
labmrd 2:dfeadd6c651c 562 #ifdef USE_SD_CARD
labmrd 2:dfeadd6c651c 563 int first_slash=file_name_in.find("/");
labmrd 2:dfeadd6c651c 564 std::string new_dir="/sd/"+file_name_in.substr(0, first_slash);
labmrd 2:dfeadd6c651c 565 std::string new_subdir="/sd/"+file_name_in.substr(0, file_name_in.find("/",first_slash+1));
labmrd 2:dfeadd6c651c 566 mkdir(new_dir.c_str(), 0777);
labmrd 2:dfeadd6c651c 567 mkdir(new_subdir.c_str(), 0777);
labmrd 2:dfeadd6c651c 568 std::string file_name="/sd/"+file_name_in+".csv";
labmrd 2:dfeadd6c651c 569 //pc.printf("subdir=\"%s\"\n",file_name.c_str());
labmrd 2:dfeadd6c651c 570 fp = fopen(file_name.c_str(), "w");
labmrd 2:dfeadd6c651c 571 //FILE *fp = fopen("/sd/data/sdtest.txt", "w");
labmrd 2:dfeadd6c651c 572 if(fp == NULL) {
labmrd 2:dfeadd6c651c 573 error("Could not open file for write\n");
labmrd 2:dfeadd6c651c 574 }
labmrd 2:dfeadd6c651c 575 fprintf(fp, "%%Starting New Trajectory\n");
labmrd 2:dfeadd6c651c 576 fprintf(fp, "%%File Name=\"%s\"\n",file_name.c_str());
labmrd 2:dfeadd6c651c 577 fprintf(fp, "%%Current Mode=AUTOMATIC\n");
labmrd 4:e44ac08027bd 578 fprintf(fp, "%%Trajectory Type=TRAPEZOIDAL\n");
labmrd 2:dfeadd6c651c 579 fprintf(fp, "%%Frequency=%f Hz\n",g_frequency);
labmrd 2:dfeadd6c651c 580 fprintf(fp, "%%Max Force=%f ??\n",g_max_force);
labmrd 2:dfeadd6c651c 581 fprintf(fp, "%%Num Cycles=%d\n",g_num_cycles);
labmrd 2:dfeadd6c651c 582 fprintf(fp, "%%Re. Direction: ,Closing=%d,Opening=%d,Undef=%d\n", DIRECTION_CLOSING , DIRECTION_OPENING , DIRECTION_SLACK_WATER );
labmrd 2:dfeadd6c651c 583 fprintf(fp, "%%PositionLeft,ForceLeft,PositionRight,ForceRight,Time(ms),Direction,CycleNum\n");
labmrd 2:dfeadd6c651c 584 #endif
labmrd 2:dfeadd6c651c 585 // We are go-times!
labmrd 5:72e92c721cd5 586 g_current_mode=MODE_AUTOMATIC;
labmrd 2:dfeadd6c651c 587 }
labmrd 2:dfeadd6c651c 588
labmrd 5:72e92c721cd5 589 if( g_current_mode==MODE_AUTOMATIC && g_current_cycle >= g_num_cycles)
labmrd 2:dfeadd6c651c 590 {
labmrd 2:dfeadd6c651c 591 // STOOOOOOOOOP
labmrd 5:72e92c721cd5 592 g_current_mode=MODE_NULL;
labmrd 2:dfeadd6c651c 593 #ifdef USE_SD_CARD
labmrd 2:dfeadd6c651c 594 // Close the file
labmrd 2:dfeadd6c651c 595 fclose(fp);
labmrd 2:dfeadd6c651c 596 fp = NULL;
labmrd 2:dfeadd6c651c 597 #endif
labmrd 2:dfeadd6c651c 598 }
labmrd 2:dfeadd6c651c 599
labmrd 5:72e92c721cd5 600 // This section of code should run whenever there is free time to save datas
labmrd 2:dfeadd6c651c 601 #ifdef USE_SD_CARD
labmrd 2:dfeadd6c651c 602 if(fp != NULL) {
labmrd 2:dfeadd6c651c 603 // Only write to SD if there is a valid file handle
labmrd 2:dfeadd6c651c 604 led3 = 1;
labmrd 2:dfeadd6c651c 605 Buffer.dumpBufferToSD(fp);
labmrd 2:dfeadd6c651c 606 led3 = 0;
labmrd 2:dfeadd6c651c 607 }
labmrd 2:dfeadd6c651c 608 #else
labmrd 5:72e92c721cd5 609 //Warning, this is a big fat stream of data, 1 minute is approx 3MB
labmrd 5:72e92c721cd5 610 //I certainly recommend using the SD card.
labmrd 2:dfeadd6c651c 611 Buffer.dumpBufferToSerial();
labmrd 2:dfeadd6c651c 612 #endif
labmrd 2:dfeadd6c651c 613
labmrd 5:72e92c721cd5 614 if(g_current_mode!=MODE_NULL && AuxSerialTimer.read_us()>30000){
labmrd 2:dfeadd6c651c 615 //Send some extra data for GUI purposes
labmrd 5:72e92c721cd5 616 #ifdef ROD_IS_RIGHT
labmrd 5:72e92c721cd5 617 float angle=0,angledot=0,angledotdot=0;
labmrd 5:72e92c721cd5 618 if(angledotdot_count>0){
labmrd 5:72e92c721cd5 619 angle =float(angle_sum )/angle_count;
labmrd 5:72e92c721cd5 620 angledot =float(angledot_sum )/angledot_count;
labmrd 5:72e92c721cd5 621 angledotdot=float(angledotdot_sum)/angledotdot_count;
labmrd 5:72e92c721cd5 622 }
labmrd 5:72e92c721cd5 623 angle_sum=0;angle_count=0;
labmrd 5:72e92c721cd5 624 angledot_sum=0;angledot_count=0;
labmrd 5:72e92c721cd5 625 angledotdot_sum=0;angledotdot_count=0;
labmrd 5:72e92c721cd5 626 #else
labmrd 5:72e92c721cd5 627 crunching_data_flag=true;
labmrd 5:72e92c721cd5 628 recent_pos.least_squares_3rd(coeffs);
labmrd 5:72e92c721cd5 629 crunching_data_flag=false;
labmrd 5:72e92c721cd5 630 float x=g_current_trajectory_time;
labmrd 5:72e92c721cd5 631 int angle =coeffs[0]+coeffs[1]*x+coeffs[2]*x*x+coeffs[3]*x*x*x;
labmrd 5:72e92c721cd5 632 int angledot = coeffs[1]+2*coeffs[2]*x+3*coeffs[3]*x*x ;
labmrd 5:72e92c721cd5 633 int angledotdot= 2*coeffs[2] +6*coeffs[3]*x ;
labmrd 5:72e92c721cd5 634 #endif
labmrd 5:72e92c721cd5 635
labmrd 5:72e92c721cd5 636
labmrd 5:72e92c721cd5 637
labmrd 5:72e92c721cd5 638 float pot_open=0.75;
labmrd 5:72e92c721cd5 639 float pot_closed=0.48;
labmrd 5:72e92c721cd5 640
labmrd 5:72e92c721cd5 641 float percent=0.0;
labmrd 5:72e92c721cd5 642 //Average the pot a bunch, it's NOISY
labmrd 5:72e92c721cd5 643 for(int i=0;i<100;i++){
labmrd 5:72e92c721cd5 644 percent+=AinJoystickFwdBk.read();
labmrd 5:72e92c721cd5 645 }
labmrd 5:72e92c721cd5 646 percent=percent/100.0;
labmrd 5:72e92c721cd5 647 percent=(pot_open-percent)/(pot_open-pot_closed);
labmrd 5:72e92c721cd5 648
labmrd 5:72e92c721cd5 649 // The 'pulling' of the trigger corresponds to open/closed
labmrd 5:72e92c721cd5 650 int potread =percent*(CLOSED_SERVO_ANGLE_LEFT -OPEN_SERVO_ANGLE_LEFT )+OPEN_SERVO_ANGLE_LEFT ;
labmrd 5:72e92c721cd5 651
labmrd 5:72e92c721cd5 652
labmrd 5:72e92c721cd5 653
labmrd 5:72e92c721cd5 654
labmrd 5:72e92c721cd5 655 //angle=left_servo_measured;
labmrd 5:72e92c721cd5 656 int loadcell=adc.read();
labmrd 5:72e92c721cd5 657
labmrd 8:cef07a8bdc42 658 //if (!calibrateDone){
labmrd 8:cef07a8bdc42 659 // Begin Calibration of load cells
labmrd 8:cef07a8bdc42 660 // Calibrate Load Cells (Does this need to get moved somewhere else?)
labmrd 8:cef07a8bdc42 661 //calibrateLoadCell();
labmrd 8:cef07a8bdc42 662 // These are for load cell initialization of the offset
labmrd 8:cef07a8bdc42 663 //calibrateTotal = (calibrateTotal + loadcell/1000.0)/2.0;
labmrd 8:cef07a8bdc42 664 //calibCntr ++;
labmrd 8:cef07a8bdc42 665 //if (calibCntr == CALIBRATION_READS){
labmrd 8:cef07a8bdc42 666 //g_loadCellZero = calibrateTotal;
labmrd 8:cef07a8bdc42 667 //Update values for thresholding based on calibration
labmrd 8:cef07a8bdc42 668 //g_thresh_force[0]=g_threshOffset1+g_loadCellZero;
labmrd 8:cef07a8bdc42 669 //g_thresh_force[1]=g_threshOffset2+g_loadCellZero;
labmrd 8:cef07a8bdc42 670 //calibrateDone = true;
labmrd 8:cef07a8bdc42 671 //}
labmrd 8:cef07a8bdc42 672 //}
labmrd 6:b4347c69816a 673 // Code to determine if we should toggle the variable of "g_we_are_grasping"
labmrd 8:cef07a8bdc42 674 if(!g_we_are_grasping && loadcell>g_loadCellZero+g_loadCellOffset && angledot<velocty_threshold){
labmrd 5:72e92c721cd5 675 //Grasp is starting
labmrd 5:72e92c721cd5 676 g_we_are_grasping=true;
labmrd 5:72e92c721cd5 677 for(int i=0;i<NUMBER_OF_TISSUES;i++){
labmrd 5:72e92c721cd5 678 g_error_norm[i]=0.0;
labmrd 5:72e92c721cd5 679 }
labmrd 5:72e92c721cd5 680 }
labmrd 8:cef07a8bdc42 681 if(g_we_are_grasping && potread > 2400 ) {//angledot>-velocty_threshold){
labmrd 5:72e92c721cd5 682 //Grasp is over
labmrd 5:72e92c721cd5 683 g_we_are_grasping=false;
labmrd 5:72e92c721cd5 684 }
labmrd 5:72e92c721cd5 685 float alpha=0;
labmrd 5:72e92c721cd5 686 std::string sstr;
labmrd 5:72e92c721cd5 687 if(g_we_are_grasping){
labmrd 5:72e92c721cd5 688 //D_x = [thetadotdot,thetadot,theta,theta^2,theta^3];
labmrd 5:72e92c721cd5 689 g_error_norm[0]+=fabs(float(loadcell)-(Phi1[0]*angledotdot+Phi1[1]*angledot+Phi1[2]*angle+Phi1[3]*angle*angle+Phi1[4]*angle*angle*angle));
labmrd 5:72e92c721cd5 690 g_error_norm[1]+=fabs(float(loadcell)-(Phi2[0]*angledotdot+Phi2[1]*angledot+Phi2[2]*angle+Phi2[3]*angle*angle+Phi2[4]*angle*angle*angle));
labmrd 5:72e92c721cd5 691
labmrd 5:72e92c721cd5 692
labmrd 5:72e92c721cd5 693 float offset1 = 100000;
labmrd 5:72e92c721cd5 694 float offset2 = 300000;
labmrd 5:72e92c721cd5 695 int tissue_id=0;
labmrd 5:72e92c721cd5 696 if(g_error_norm[1]>g_error_norm[0]){alpha=(g_error_norm[1]-g_error_norm[0])/(g_error_norm[1]+offset1);sstr="HARD";tissue_id=0;}
labmrd 5:72e92c721cd5 697 if(g_error_norm[0]>g_error_norm[1]){alpha=(g_error_norm[0]-g_error_norm[1])/(g_error_norm[0]+offset2);sstr="SOFT";tissue_id=1;}
labmrd 5:72e92c721cd5 698
labmrd 5:72e92c721cd5 699 float force_err=loadcell-g_thresh_force[tissue_id];
labmrd 5:72e92c721cd5 700 float k=20/0.1e6;
labmrd 5:72e92c721cd5 701 g_command_corrected=(1-alpha)*potread+alpha*(k*force_err+angle);
labmrd 5:72e92c721cd5 702 }else{
labmrd 5:72e92c721cd5 703 g_command_corrected=potread;
labmrd 5:72e92c721cd5 704 }
labmrd 5:72e92c721cd5 705
labmrd 5:72e92c721cd5 706 //std::vector<int> data_in=<angle, angledot, angledotdot, loadcell, potread>
labmrd 7:b4b95e5f0fce 707 printf("Data:,%6.3f,%0.0f,% 2.3f,% 2.3f,%d,%d,%0.0f,%0.0f,%12.3f,%s\n",mytimer.read_us()/1000.0,angle, angledot, angledotdot, loadcell, potread,g_error_norm[1]*angle,g_error_norm[1],g_calibration_offset,sstr.c_str());
labmrd 5:72e92c721cd5 708 //printf("%s",recent_pos.get_string().c_str());
labmrd 5:72e92c721cd5 709 // printf("<%d,%d,%d,%d,%d,%d,%d> ",tempSpindleData.myServoData[LEFT_SERVO_INDEX].pos,
labmrd 5:72e92c721cd5 710 // tempSpindleData.myServoData[LEFT_SERVO_INDEX].force,
labmrd 5:72e92c721cd5 711 // tempSpindleData.myServoData[RIGHT_SERVO_INDEX].pos,
labmrd 5:72e92c721cd5 712 // tempSpindleData.myServoData[RIGHT_SERVO_INDEX].force,
labmrd 5:72e92c721cd5 713 // tempSpindleData.time,
labmrd 5:72e92c721cd5 714 // tempSpindleData.direction,
labmrd 5:72e92c721cd5 715 // tempSpindleData.cycle);
labmrd 5:72e92c721cd5 716 // printf(" %dus", worst_latency);
labmrd 5:72e92c721cd5 717 // worst_latency=0;
labmrd 5:72e92c721cd5 718 // printf(" %0.0fbps\n", bits_received*1000.0/AuxSerialTimer.read_ms());
labmrd 5:72e92c721cd5 719 // bits_received=0;
labmrd 2:dfeadd6c651c 720 AuxSerialTimer.reset();
labmrd 2:dfeadd6c651c 721 }
labmrd 2:dfeadd6c651c 722
mbed_official 0:8a555873b7d3 723 }
mbed_official 0:8a555873b7d3 724 }