Maik Overmars / Robot_Software

Dependencies:   HIDScope MODSERIAL QEI biquadFilter mbed

Fork of Robot_Software by Bram Jonkheer

Revision:
1:ce487c9929dd
Parent:
0:ef81b9f14f58
diff -r ef81b9f14f58 -r ce487c9929dd main.cpp
--- a/main.cpp	Fri Oct 19 07:50:39 2018 +0000
+++ b/main.cpp	Mon Oct 22 11:10:41 2018 +0000
@@ -4,37 +4,48 @@
 #include "HIDScope.h"
 #include "BiQuad.h"
 #include "PID_controller.h"
-#include "Servo.h"
+#include "kinematics.h"
 
 //Define objects
+MODSERIAL pc(USBTX, USBRX);
+HIDScope    scope(2);
+
 AnalogIn    emg0( A0 );
 AnalogIn    emg1( A1 );
-HIDScope    scope(2);
+
 PwmOut      motor1_pwm(D5);
+DigitalOut  motor1_dir(D4);
 PwmOut      motor2_pwm(D7);
 DigitalOut  motor2_dir(D6);
-DigitalOut  directionpin(D4);
+
 AnalogIn    potmeter1(A2);
 AnalogIn    potmeter2(A3);
 DigitalIn   button(D0);
+
 Ticker Sample;
-Timer t;
+Timer state_timer;
 
-enum States {failure, wait, calib_enc, calib_emg, operational, demo}; //All possible robot states
+enum States {failure, waiting, calib_enc, calib_emg, operational, demo}; //All possible robot states
 
 //Global variables/objects
 States current_state;
 Ticker loop_ticker; //The Ticker object that will ensure perfect timing of our looping code
-float u, emg_signal_raw_1, processed_emg_1, robot_end_point, motor1pwm, motor1dir, motor2pwm, motor2dir, motor_angle, motor_counts; //will be set by the motor_controller function
+float e, u1, u2, emg_signal_raw_0, processed_emg_0, emg_signal_raw_1, processed_emg_1, robot_end_point, reference_end_point, motor_angle, motor_counts, q_ref; //will be set by the motor_controller function
+int counts_per_rotation = 32;
+bool state_changed = false;
+
+float processing_chain_emg(int num) {
+    return 6.0;
+}
 
 void measure_all() 
 {
     motor_angle = motor_counts*2.0f*3.1415926535f/counts_per_rotation; //do this here, and not in the encoder interrupt, to reduce computational load
-    robot_end_point = forwardkinematics_function();  //motor_angle is global, this function ne
-    emg_signal_raw_1 = emg1.read(); //sample analog voltages (all sampling theory applies, you might get aliasing etc.)
-    emg_signal_raw_2 = emg2.read();
-    processed_emg_1 = processing_chain_emg_1();  // some function ‘float my_emg_processing_chain()’ that returns a float. The raw emg is global
-    processed_emg_2 = processing_chain_emg_2();
+    robot_end_point = forwardkinematics_function(motor_angle);  //motor_angle is global, this function ne
+    emg_signal_raw_0 = emg0.read(); //sample analog voltages (all sampling theory applies, you might get aliasing etc.)
+    emg_signal_raw_1 = emg1.read();
+    processed_emg_0 = processing_chain_emg(0);  // some function ‘float my_emg_processing_chain()’ that returns a float. The raw emg is global
+    processed_emg_1 = processing_chain_emg(1);
 }
 
 void output_all() {
@@ -42,14 +53,15 @@
     motor1_dir = u1 > 0.5f;
     motor2_pwm = fabs(u2);
     motor2_dir = u2 > 0.5f;
+    static int output_counter = 0;
     output_counter++;
-    if (output_counter == 100) {serial.printf(“Something something... %f”,u); output_counter = 0;}  //Print to screen at 10 Hz with MODSERIAL
+    if (output_counter == 100) {pc.printf("Something something... %f",u1); output_counter = 0;}  //Print to screen at 10 Hz with MODSERIAL
 }
 
 void state_machine() {
     switch(current_state) { //States can be: failure, wait, calib_enc, calib_emg, operational, demo,
-        case wait:  //Nothing useful here, maybe a blinking LED for fun and communication to the user
-            if (calib_button.read()==true) 
+        case waiting:  //Nothing useful here, maybe a blinking LED for fun and communication to the user
+            if (button.read()==true) 
             {
                 current_state = calib_enc; //the NEXT loop we will be in calib_enc state
             }
@@ -58,12 +70,13 @@
         case calib_enc:
             if (state_changed==true) 
             {
-                state_time.reset();
+                state_timer.reset();
                 state_timer.start();
                 state_changed = false;
             }
-            u = 0.6f; //a low PWM value to move the motors slowly (0.0 to 0.45 don’t do much due to friction)
-            if (fabs(motor1.velocity()) < 0.1f && state_timer.read() > 5.0f) {
+            u1 = 0.6f; //a low PWM value to move the motors slowly (0.0 to 0.45 don’t do much due to friction)
+            // fabs(motor1.velocity()) < 0.1f && 
+            if (state_timer.read() > 5.0f) {
                 current_state = calib_emg; //the NEXT loop we will be in calib_emg state
                 state_changed = true;
             }
@@ -71,29 +84,34 @@
             
         case calib_emg:     //calibrate emg-signals
             
+            break;
         
         case operational:       //interpreting emg-signals to move the end effector
-            if (state_changed==true) { ... }
-            end_effector_reference_position = some_function(processed_emg);
-            if (... some state tr. guard ...) { ... }
+            if (state_changed==true) { int x = 5; }
+            // example
+            reference_end_point = robot_end_point + processed_emg_0;
+            if (button.read() == true) { current_state = demo; }
             
             break;
             
         case demo: //moving according to a specified trajectory
             
+            if (button.read() == true) { current_state = demo; }
+            
             break;
         
         case failure: //no way to get out
-            u = 0.0f;
+            u1 = 0.0f;
             break;
+    }
 }
 
 void motor_controller() 
 {
     if (current_state >= operational) { // we can (ab)use the fact that an enum is actually an integer, so math/logic rules still apply
-        q_ref = inverse_kinematics(end_effector_reference_position); //many different states can modify your reference position, so just do the inverse kinematics once, here
-        e = q_ref – q_meas; //tracking error
-        u = PID_controller(e); //feedback controller or with possibly fancy controller additions...;
+        q_ref = inversekinematics_function(reference_end_point); //many different states can modify your reference position, so just do the inverse kinematics once, here
+        e = q_ref - motor_angle; //tracking error (q_ref - q_meas)
+        u1 = PID_controller(e); //feedback controller or with possibly fancy controller additions...;
         } //otherwise we just don’t mess with the value of control variable ‘u’ that is set somewhere in the state-machine.
 }
 
@@ -105,15 +123,15 @@
     output_all();               //Output relevant signals, messages, screen outputs, LEDs etc.
 }
 
+
 int main() 
 {
     pc.baud(115200);
-    pwmpin.period_us(60);
-    current_state = wait; //we start in state ‘wait’ and current_state can be accessed by all functions
-    u = 0.0f; //initial output to motors is 0.
+    motor1_pwm.period_us(60);
+    motor2_pwm.period_us(60);
+    current_state = waiting; //we start in state ‘waiting’ and current_state can be accessed by all functions
+    u1 = 0.0f; //initial output to motors is 0.
     loop_ticker.attach(&loop_function, 0.001f); //Run the function loop_function 1000 times per second
     
-    float counts_per_rotation = 32;
-    
     while (true) { }  //Do nothing here (timing purposes)
 }