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: QEI chair_BNO055 pid ros_lib_kinetic
Dependents: wheelchaircontrolrealtimeROS
Fork of wheelchaircontrol by
wheelchair.cpp
- Committer:
- ryanlin97
- Date:
- 2018-08-31
- Revision:
- 21:69df88af7c46
- Parent:
- 19:df4257c75ed0
File content as of revision 21:69df88af7c46:
#include "wheelchair.h"
Serial qei(D1, D0);
DigitalOut on(D12);
DigitalOut off(D11);
DigitalOut up(D2);
DigitalOut down(D3);
bool manual_drive = false;
double encoder_distance;
double curr_yaw;
double Setpoint, Output, Input;
PID myPID(&curr_yaw, &Output, &Setpoint, 5.5, 0, .0036, P_ON_E, DIRECT);
PID myPIDDistance(&Input, &Output, &Setpoint, 5.5, .00, 0.0036, P_ON_E, DIRECT);
void Wheelchair::compass_thread() {
curr_yaw = imu->yaw();
}
double Wheelchair::readEncoder() {
char input[64] = {0};
for (int i=0; input[i-1] != '\n'; i++) {
while (true) {
//pc.printf("%f\r\n", ti.read());
if (ti->read() > .02) break;
if (qei.readable()) {
input[i]= qei.getc();
break;
}
}
}
return atoi(input);
}
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);
Wheelchair::stop();
imu->setup();
out = pc;
out->printf("wheelchair setup done \n");
ti = time;
wheel = qei;
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\n", imu->yaw());
}
void Wheelchair::forward()
{
x->write(high);
y->write(def+offset);
}
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)
{
float pid_yaw;
bool overturn = false;
out->printf("pid right\r\r\n");
x->write(def);
Setpoint = curr_yaw + deg;
pid_yaw = curr_yaw;
if(Setpoint > 360) {
overturn = true;
}
myPID.SetTunings(5.5,0, 0.00345);
myPID.SetOutputLimits(0, def - low - .15);
myPID.SetControllerDirection(DIRECT);
while(pid_yaw < Setpoint - 3){
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)
{
float pid_yaw;
bool overturn = false;
out->printf("pid Left\r\r\n");
x->write(def);
Setpoint = curr_yaw - deg;
pid_yaw = curr_yaw;
if(Setpoint < 0) {
overturn = true;
}
myPID.SetTunings(5,0, 0.004);
myPID.SetOutputLimits(0,high - def -.12);
myPID.SetControllerDirection(REVERSE);
while(pid_yaw > Setpoint + 3){
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);
}
}
double Wheelchair::turn_right(int deg)
{
bool overturn = false;
out->printf("turning right\n");
double start = curr_yaw;
double final = start + deg;
if(final > 360) {
final -= 360;
overturn = true;
}
out->printf("start %f, final %f\n", start, final);
double curr = -1;
while(curr <= final - 30) {
Wheelchair::right();
if( out->readable()) {
out->printf("stopped\n");
Wheelchair::stop();
return;
}
curr = curr_yaw;
if(overturn && curr > (360 - deg) ) {
curr = 0;
}
}
out->printf("done turning start %f final %f\n", start, final);
Wheelchair::stop();
//delete me
wait(5);
float correction = final - curr_yaw;
out->printf("final pos %f actual pos %f\n", final, curr_yaw);
Wheelchair::turn_left(abs(correction));
Wheelchair::stop();
wait(5);
out->printf("curr_yaw %f\n", curr_yaw);
return final;
}
double Wheelchair::turn_left(int deg)
{
bool overturn = false;
out->printf("turning left\n");
double start = curr_yaw;
double final = start - deg;
if(final < 0) {
final += 360;
overturn = true;
}
out->printf("start %f, final %f\n", start, final);
double curr = 361;
while(curr >= final) {
Wheelchair::left();
if( out->readable()) {
out->printf("stopped\n");
Wheelchair::stop();
return;
}
curr = curr_yaw;
if(overturn && curr >= 0 && curr <= start ) {
curr = 361;
}
}
out->printf("done turning start %f final %f\n", start, final);
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);
float correction = finalpos - curr_yaw;
out->printf("final pos %f actual pos %f\n", finalpos, curr_yaw);
//if(abs(correction) > turn_precision) {
out->printf("correcting %f\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::turn_on() {
on = 1;
wait(1);
on = 0;
}
void Wheelchair::turn_off() {
off = 1;
wait(1);
off = 0;
}
void Wheelchair::pid_forward(double mm)
{
y->write(def + offset);
wheel->reset();
Input = 0;
out->printf("pid foward\r\n");
Setpoint = mm-20;
// Setpoint = wheel_right.getDistance(37.5)+mm;
myPIDDistance.SetTunings(5,0, 0.004);
myPIDDistance.SetOutputLimits(0,high - def - 0.15);
myPIDDistance.SetControllerDirection(DIRECT);
while(Input < Setpoint-5){//pid_yaw < Setpoint + 2) {
if(out->readable()){
Wheelchair::stop();
break;}
Input = wheel->getDistance(53.975);
//out->printf("input foward %d\r\n", wheel->getPulses());
wait(.05);
myPIDDistance.Compute();
x->write(Output + def);
out->printf("distance %f\r\n", Input);
}
}
void Wheelchair::desk() {
Wheelchair::pid_forward(5461);
Wheelchair::pid_right(87);
Wheelchair::pid_forward(3658);
Wheelchair::pid_left(87);
Wheelchair::pid_forward(3734);
}
void Wheelchair::kitchen() {
Wheelchair::pid_forward(5461);
Wheelchair::pid_right(87);
Wheelchair::pid_forward(3658);
Wheelchair::pid_left(87);
Wheelchair::pid_forward(305);
}
void Wheelchair::back() {
Wheelchair::pid_right(177);
Wheelchair::pid_forward(3700);
}
