Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: HIDScope biquadFilter mbed QEI
main.cpp
- Committer:
- WouterJS
- Date:
- 2018-10-26
- Revision:
- 1:a9c933f1dc71
- Parent:
- 0:3710031b2621
- Child:
- 2:fa90eaa14f99
File content as of revision 1:a9c933f1dc71:
#include "mbed.h"
#include "BiQuad.h"
#include "HIDScope.h"
#include <stdio.h>
#include <math.h>
#include <iostream>
#include "QEI.h"
Serial pc(USBTX,USBRX);
Timer timer;
float Ts = 0.002;
DigitalIn buttonR(D2);//rigth button on biorobotics shield
DigitalIn buttonL(D3);//left button on biorobotics shield
int sensor_sensitivity = 32;
int gear_ratio = 131;
float full_ratio = gear_ratio*sensor_sensitivity*4;
QEI Encoder1(D10,D11,NC,sensor_sensitivity); //First one is B, Second one is A
QEI Encoder2(D12,D13,NC,sensor_sensitivity); //
int counts_m1 = 0;
int counts_m2 = 0;
int counts_m1_prev = 0;
int counts_m2_prev = 0;
float deg_m1 = 0;
float deg_m2 = 0;
//Vector2d twist(0,0);
//Matrix2f jacobian(0, 0, 0, 0), inv_jacobian(0, 0, 0, 0);
DigitalOut motor1_direction(D4);// draairichting motor 1 (1 is CW encoder als je daar op kijkt en CW shaft als je daar op kijkt)
PwmOut motor1_speed_control(D5);//aanstuursnelheid motor 1
PwmOut motor2_speed_control(D6);//aanstuursnelheid motor 2
DigitalOut motor2_direction(D7);// draairichting motor 2 (1 is CW encoder als je daar op kijkt en CW shaft als je daar op kijkt)
enum States {failure, waiting, calib_motor, calib_emg, operational, demo};
enum Operations {rest, forward, backward, up, down};
States current_state = calib_motor;
Operations movement = rest;
float max1 = 0; //initial threshold value for emg signals, changes during calibration left arm
float max2 = 0; // right arm
float threshold1;
float threshold2;
float thresholdtime = 1.0; // time waiting before switching modes
Ticker loop_timer;
Ticker sample_timer;
Ticker sample_timer2;
HIDScope scope( 5 );
AnalogIn raw_emg1_input(A0);//input for first emg signal 1, for the modes
AnalogIn raw_emg2_input(A1);//input for first emg signal 2, for the strength
volatile float emg1_input;
volatile float emg2_input;
volatile float raw_filteredsignal1;//the first filtered emg signal 1
volatile float raw_filteredsignal2;//the first filtered emg signal 2
volatile float filteredsignal1;//the first filtered emg signal 1
volatile float filteredsignal2;//the first filtered emg signal 2
bool state_changed = false;
float high1;
float abs1;
float low1;
void filterall()
{
//Highpass Biquad 5 Hz
static BiQuad HighPass1(0.95653708, -1.91307417, 0.95653708, -1.91118480, 0.91496354);
high1 = HighPass1.step(emg1_input);
static BiQuad HighPass2(0.95653708, -1.91307417, 0.95653708, -1.91118480, 0.91496354);
float high2 = HighPass2.step(emg2_input);
// Rectify the signal(absolute value)
abs1 = fabs(high1);
float abs2 = fabs(high2);
//Lowpass Biquad 10 Hz
static BiQuad LowPass1(0.00362164, 0.00724327, 0.00362164, -1.82267251, 0.83715906);
low1 = LowPass1.step(abs1);
static BiQuad LowPass2(0.00362164, 0.00724327, 0.00362164, -1.82267251, 0.83715906);
float low2 = LowPass2.step(abs2);
raw_filteredsignal1 = low1;
raw_filteredsignal2 = low2;
}
void measureall(){ // changes all variables according in sync with the rest of the code
emg1_input = raw_emg1_input.read();
emg2_input = raw_emg2_input.read();
filteredsignal1 = raw_filteredsignal1;
filteredsignal2 = raw_filteredsignal2;
//Reading of motor
counts_m1 = Encoder1.getPulses() - counts_m1_prev;
counts_m2 = Encoder1.getPulses() - counts_m2_prev;
deg_m1 = deg_m1 + counts_m1*(360/(full_ratio));
deg_m2 = deg_m2 + counts_m2*(360/(full_ratio));
counts_m1_prev = Encoder1.getPulses();
counts_m2_prev = Encoder2.getPulses();
}
void scopedata()
{
scope.set(0,emg1_input); //
scope.set(1,high1); //
scope.set(2,abs1); //
scope.set(3,low1);//
scope.set(4,filteredsignal1);
scope.send(); // send info to HIDScope server
}
//////////////////// MOVEMENT STATES
void do_forward(){
//twist << 1, 0;
//Vector2d twistf(0,0);
//twistf << 1, 0;
if (filteredsignal2 > threshold2){
//double abs_sig = (filteredsignal2 - (0.5*max2))/(0.5*max2);
//twist = twistf * abs_sig;
}
if( timer.read() > thresholdtime && filteredsignal1 > threshold1)
{
movement = backward;
timer.reset();
}
}
void do_backward(){
if( timer.read() > thresholdtime && filteredsignal1 > threshold1)
{
movement = up;
timer.reset();
}
}
void do_up(){
//Code for moving up
if( timer.read() > thresholdtime && filteredsignal1 > threshold1)
{
movement = down;
timer.reset();
}
}
void do_down(){
//Code for moving down
if( timer.read() > thresholdtime && filteredsignal1 > threshold1)
{
movement = rest;
timer.reset();
}
}
void do_wait(){
if ( filteredsignal2 > threshold2) {//
current_state = waiting;
state_changed = true;
}
if( timer.read() > thresholdtime && filteredsignal1 > threshold1)
{
movement = forward;
timer.reset();
}
}
///////////END MOVEMENT STATES/////////////////////////
///////////ROBOT ARM STATES ///////////////////////////
void do_state_failure(){
}
bool on = true;
void do_state_calib_motor(){
if (state_changed==true) {
state_changed = false;
}
if(on){
timer.reset();
motor1_direction = 1; //set motor 1 to run counterclockwise (positive) direction for calibration
motor1_speed_control = 0.3;//to make sure the motor will not run at too high velocity
motor2_direction = 0; // set motor 2 to run clockwise (negative) direction
motor2_speed_control = 0.3;
on = false;
}
int deriv1 = fabs((counts_m1 - counts_m1_prev)/Ts);
int deriv2 = fabs((counts_m2 - counts_m2_prev)/Ts);
if ( timer.read() > 5 && deriv1 < 1 && deriv2 < 1) {
motor1_speed_control = 0;
motor2_speed_control = 0;
current_state = calib_emg;
timer.reset();
state_changed = true;
}
}
void do_state_calib_emg(){
if (state_changed==true) {
state_changed = false;
}
if(filteredsignal1 > max1){//calibrate to a new maximum
max1 = filteredsignal1;
threshold1 = 0.5*max1;
}
if(filteredsignal2 > max2){//calibrate to a new maximum
max2 = filteredsignal2;
threshold2 = 0.5 * max2;
}
if (timer.read() > 10 && filteredsignal1 > threshold1 && filteredsignal2 > threshold2) {
current_state = operational;
timer.reset();
state_changed = true;
}
}
void do_state_operational(){
if (state_changed==true) {
state_changed = false;
}
switch(movement) {// a separate function for what happens in each state
case rest:
do_wait();
break;
case forward:
do_forward();
break;
case backward:
do_backward();
break;
case up:
do_up();
break;
case down:
do_down();
break;
}
if (movement == rest && filteredsignal2 > threshold2) {
current_state = waiting;
state_changed = true;
}
}
void do_state_waiting(){
if (state_changed==true) {
state_changed = false;
}
if (filteredsignal1 > threshold1 && filteredsignal2 > threshold2) {
current_state = operational;
state_changed = true;
}
}
//////////////// END ROBOT ARM STATES //////////////////////////////
void motor_controller(){
float q1;
float q2;
//q1 defined
//q2 defined
//float L0 = 0.1;
//float L1 = 0.1;
//float L2 = 0.4;
//jacobian << L1, L2*sin(q1)+L1,-L0,-L0 - L2*cos(q1);
//inv_jacobian = jacobian.inverse();
//Vector2d reference_vector = inv_jacobian*twist;
//float ref_v1 = reference_vector(0);
//float ref_v2 = reference_vector(1);
//float ref_q1 = 0;
//ref_q1 = ref_p1 + 0.002*ref_v1;
// float ref_q2 = 0;
//ref_q2 = ref_p2 + 0.002*ref_v2;
}
void loop_function() { //Main loop function
measureall();
switch(current_state) {
case failure:
do_state_failure(); // a separate function for what happens in each state
break;
case calib_motor:
do_state_calib_motor();
break ;
case calib_emg:
do_state_calib_emg();
break;
case operational:
do_state_operational();
break;
case waiting:
do_state_waiting();
break;
}
motor_controller();
// Outputs data to the computer
}
int main()
{
motor1_speed_control.period_us(60); //60 microseconds PWM period, 16.7 kHz
timer.start();
loop_timer.attach(&loop_function, Ts);
sample_timer.attach(&scopedata, Ts);
sample_timer2.attach(&filterall, Ts);
//led_red = 1;
//led_green = 1;
while (true) {
}
}