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: QEI2 PID Watchdog VL53L1X_Filter BNOWrapper ros_lib_kinetic
wheelchair.cpp
- Committer:
- jvfausto
- Date:
- 2018-08-31
- Revision:
- 19:71a6621ee5c3
- Parent:
- 18:663b6d693252
- Child:
- 20:f42db4ae16f0
File content as of revision 19:71a6621ee5c3:
#include "wheelchair.h"
bool manual_drive = false;
volatile float north;
//volatile double curr_yaw;
double curr_yaw;
double encoder_distance;
char myString[64];
volatile double Setpoint, Output, Input, Input2;
volatile double pid_yaw, Distance, Setpoint2, Output2, encoder_distance2;
PID myPID(&pid_yaw, &Output, &Setpoint, 5.5, .00, 0.0036, P_ON_E, DIRECT);
PID myPIDDistance(&Input, &Output, &Setpoint, 5.5, .00, 0.0025, P_ON_E, DIRECT);
//PID myPIDDistance2(&Input2, &Output2, &Setpoint2, 5.5, .00, 0.0036, P_ON_E, DIRECT);
//QEI wheel_right(D0, D1, NC, 450);
void Wheelchair::compass_thread() {
curr_yaw = imu->yaw();
north = boxcar(imu->angle_north());
}
Wheelchair::Wheelchair(PinName xPin, PinName yPin, Serial* pc, Timer* time, QEI* qei)
{
x = new PwmOut(xPin);
y = new PwmOut(yPin);
imu = new chair_BNO055(pc, time);
//imu = new chair_MPU9250(pc, time);
Wheelchair::stop();
imu->setup();
out = pc;
wheel = qei;
out->printf("wheelchair setup done \r\n");
ti = time;
//wheel = new QEI(Encoder1, Encoder2, NC, EncoderReadRate);
myPID.SetMode(AUTOMATIC);
}
/*
* joystick has analog out of 200-700, scale values between 1.3 and 3.3
*/
void Wheelchair::move(float x_coor, float y_coor)
{
float scaled_x = ((x_coor * 1.6f) + 1.7f)/3.3f;
float scaled_y = (3.3f - (y_coor * 1.6f))/3.3f;
// lowPass(scaled_x);
//lowPass(scaled_y);
x->write(scaled_x);
y->write(scaled_y);
//out->printf("yaw %f\r\r\n", imu->yaw());
}
void Wheelchair::forward()
{
x->write(high);
y->write(def+offset);
// out->printf("distance %f\r\n", wheel_right.getDistance(37.5));
}
void Wheelchair::backward()
{
x->write(low);
y->write(def);
}
void Wheelchair::right()
{
x->write(def);
y->write(low);
}
void Wheelchair::left()
{
x->write(def);
y->write(high);
}
void Wheelchair::stop()
{
x->write(def);
y->write(def);
}
// counter clockwise is -
// clockwise is +
void Wheelchair::pid_right(int deg)
{
bool overturn = false;
out->printf("pid right\r\r\n");
x->write(def);
Setpoint = curr_yaw + deg;
pid_yaw = curr_yaw;
if(Setpoint > 360) {
// Setpoint -= 360;
overturn = true;
}
myPID.SetTunings(5.5,0, 0.0035);
myPID.SetOutputLimits(0, def-low-.15);
myPID.SetControllerDirection(DIRECT);
while(pid_yaw < Setpoint - 3){//curr_yaw <= Setpoint) {
if(overturn && curr_yaw < Setpoint-deg-1)
{
pid_yaw = curr_yaw + 360;
}
else
pid_yaw = curr_yaw;
myPID.Compute();
double tempor = -Output+def;
y->write(tempor);
out->printf("curr_yaw %f\r\r\n", curr_yaw);
out->printf("Setpoint = %f \r\n", Setpoint);
wait(.05);
}
Wheelchair::stop();
out->printf("done \r\n");
}
void Wheelchair::pid_left(int deg)
{
bool overturn = false;
out->printf("pid Left\r\r\n");
x->write(def);
Setpoint = curr_yaw - deg;
pid_yaw = curr_yaw;
if(Setpoint < 0) {
// Setpoint += 360;
overturn = true;
}
myPID.SetTunings(5,0, 0.004);
myPID.SetOutputLimits(0,high-def-.12);
myPID.SetControllerDirection(REVERSE);
while(pid_yaw > Setpoint+3){//pid_yaw < Setpoint + 2) {
myPID.Compute();
if(overturn && curr_yaw > Setpoint+deg+1)
{
pid_yaw = curr_yaw - 360;
}
else
pid_yaw = curr_yaw;
double tempor = Output+def;
y->write(tempor);
out->printf("curr_yaw %f\r\n", curr_yaw);
wait(.05);
}
Wheelchair::stop();
}
void Wheelchair::pid_turn(int deg) {
if(deg > 180) {
deg -= 360;
}
else if(deg < -180) {
deg+=360;
}
int turnAmt = abs(deg);
ti->reset();
if(deg >= 0){
Wheelchair::pid_right(turnAmt);
}
else {
Wheelchair::pid_left(turnAmt);
}
}
void Wheelchair::pid_forward(double mm)
{
mm -= 20;
Input = 0;
wheel->reset();
out->printf("pid foward\r\n");
double tempor;
Setpoint = mm;
// Setpoint = wheel_right.getDistance(37.5)+mm;
myPIDDistance.SetTunings(5,0, 0.004);
myPIDDistance.SetOutputLimits(0,high-def-.15);
myPIDDistance.SetControllerDirection(DIRECT);
y->write(def+offset);
while(Input < Setpoint-5){//pid_yaw < Setpoint + 2) {
if(out->readable())
break;
Input = wheel->getDistance(53.975);
//out->printf("input foward %d\r\n", wheel->getPulses());
wait(.05);
myPIDDistance.Compute();
tempor = Output + def;
x->write(tempor);
out->printf("distance %f\r\n", Input);
}
}
void Wheelchair::pid_reverse(double mm)
{
/* qei.putc('r');
out->printf("pid reverse\r\n");
double tempor;
Setpoint2 = mm;
// Setpoint = wheel_right.getDistance(37.5)+mm;
myPIDDistance.SetTunings(5,0, 0.004);
myPIDDistance.SetOutputLimits(0,def);
myPIDDistance.SetControllerDirection(REVERSE);
y->write(def);
while(encoder_distance > Setpoint2+5){//pid_yaw < Setpoint + 2) {
int i;
qei.putc('h');
//qei.gets(myString, 10);
ti->reset();
for (i=0; myString[i-1] != '\n'; i++) {
while (true) {
//pc.printf("%f\r\n", ti.read());
if (ti->read() > .02) break;
if (qei.readable()) {
myString[i]= qei.getc();
break;
}
}
}
myString[i-1] = 0;
double tempor = atof(myString);
out->printf("displacement = %f\r\n", tempor);
if(abs(tempor - encoder_distance) < 500)
{
encoder_distance = tempor;
out->printf("this is fine\r\n");
}
for(i = 0; i < 64; i++)
{
myString[i] = 0;
}
Input = encoder_distance;
out->printf("input foward %f\r\n", Input);
wait(.1);
myPIDDistance.Compute();
// get value from encoder2
qei.putc('k');
ti->reset();
for (i=0; myString[i-1] != '\n'; i++) {
while (true) {
//pc.printf("%f\r\n", ti.read());
if (ti->read() > .02) break;
if (qei.readable()) {
myString[i]= qei.getc();
break;
}
}
}
myString[i-1] = 0;
double tempor2 = atof(myString);
out->printf("displacement = %f\r\n", tempor2);
if(abs(tempor - encoder_distance) < 500)
{
encoder_distance = tempor;
out->printf("this is fine\r\n");
}
if(abs(tempor2 - encoder_distance2) < 500)
{
encoder_distance2 = tempor2;
out->printf("this is fine\r\n");
}
for(i = 0; i < 64; i++)
{
myString[i] = 0;
}
tempor = Output;
x->write(tempor);
out->printf("distance %f\r\n", encoder_distance);
}*/
}
double Wheelchair::turn_right(int deg)
{
bool overturn = false;
out->printf("turning right\r\n");
double start = curr_yaw;
double final = start + deg;
if(final > 360) {
final -= 360;
overturn = true;
}
out->printf("start %f, final %f\r\n", start, final);
double curr = -1;
while(curr <= final - 30) {
Wheelchair::right();
if( out->readable()) {
out->printf("stopped\r\n");
Wheelchair::stop();
return;
}
curr = curr_yaw;
if(overturn && curr > (360 - deg) ) {
curr = 0;
}
}
out->printf("done turning start %f final %f\r\n", start, final);
Wheelchair::stop();
//delete me
wait(5);
float correction = final - curr_yaw;
out->printf("final pos %f actual pos %f\r\n", final, curr_yaw);
Wheelchair::turn_left(abs(correction));
Wheelchair::stop();
wait(5);
out->printf("curr_yaw %f\r\n", curr_yaw);
return final;
}
double Wheelchair::turn_left(int deg)
{
bool overturn = false;
out->printf("turning left\r\n");
double start = curr_yaw;
double final = start - deg;
if(final < 0) {
final += 360;
overturn = true;
}
out->printf("start %f, final %f\r\n", start, final);
double curr = 361;
while(curr >= final) {
Wheelchair::left();
if( out->readable()) {
out->printf("stopped\r\n");
Wheelchair::stop();
return;
}
curr = curr_yaw;
if(overturn && curr >= 0 && curr <= start ) {
curr = 361;
}
}
out->printf("done turning start %f final %f\r\n", start, final);
Wheelchair::stop();
//delete me
wait(2);
/*
float correction = final - curr_yaw;
out->printf("final pos %f actual pos %f\r\n", final, curr_yaw);
Wheelchair::turn_right(abs(correction));
Wheelchair::stop();
*/
return final;
}
void Wheelchair::turn(int deg)
{
if(deg > 180) {
deg -= 360;
}
else if(deg < -180) {
deg+=360;
}
double finalpos;
int turnAmt = abs(deg);
//ti->reset();
/*
if(deg >= 0){
finalpos = Wheelchair::turn_right(turnAmt);
}
else {
finalpos = Wheelchair::turn_left(turnAmt);
}
*/
wait(2);
float correction = finalpos - curr_yaw;
out->printf("final pos %f actual pos %f\r\n", finalpos, curr_yaw);
//if(abs(correction) > turn_precision) {
out->printf("correcting %f\r\n", correction);
//ti->reset();
Wheelchair::turn_left(curr_yaw - finalpos);
return;
//}
}
float Wheelchair::getDistance() {
return wheel->getDistance(Diameter);
}
void Wheelchair::resetDistance(){
wheel->reset();
}
void Wheelchair::desk() {
Wheelchair::pid_forward(5461);
Wheelchair::pid_right(87);
Wheelchair::pid_forward(3658);
Wheelchair::pid_right(87);
Wheelchair::pid_forward(3658);
}
void Wheelchair::kitchen() {
Wheelchair::pid_forward(5461);
Wheelchair::pid_right(85);
Wheelchair::pid_forward(3658);
Wheelchair::pid_left(90);
Wheelchair::pid_forward(305);
}
void Wheelchair::desk_to_kitchen(){
Wheelchair::pid_right(180);
Wheelchair::pid_forward(3700);
}