#include "remotecomm.nqh"
#define ENC_TIMER 1
#define PACKET_TIMER 2
#define LEFT_ENC SENSOR_3
#define RIGHT_ENC SENSOR_1
#define SONAR SENSOR_2
#define LEFT_OUT OUT_C
#define RIGHT_OUT OUT_A
#define LEFT_OUT_NUM 2
#define RIGHT_OUT_NUM 0
#define LEFT_FWD OUT_FWD
#define LEFT_REV OUT_REV
#define RIGHT_FWD OUT_FWD
#define RIGHT_REV OUT_REV
#define LEFT_DIR 1
#define RIGHT_DIR 1
#define CLICK 105
#define BOT_RADIUS 63
#define MAX_VEL 700
int left_mult;
int right_mult;
int left_out, right_out;
int left_dir, right_dir;
void getDiff(int &diff) {
diff = left_mult * LEFT_ENC * LEFT_DIR * left_dir
- right_mult * RIGHT_ENC * RIGHT_DIR * right_dir;
}
int adjustby;
task drive() {
int l_power, r_power;
int target;
int diff, olddiff;
target = 4;
l_power = 0;
r_power = 0;
ClearSensor(LEFT_ENC);
ClearSensor(RIGHT_ENC);
l_power = 1;
r_power = 1;
SetPower (LEFT_OUT, l_power);
SetPower (RIGHT_OUT, r_power);
olddiff = 0;
adjustby = 1;
while (1) {
getDiff(diff);
if (diff * olddiff < 0)
adjustby -= 1;
else if (abs(diff) > abs(olddiff))
adjustby += 2;
else if (abs(diff) <= 1)
adjustby -= 1;
else if ((diff == olddiff) && (diff != 0))
adjustby += 1;
if (adjustby < 1)
adjustby = 1;
else if (adjustby > 5)
adjustby = 5;
if (diff > 0) {
if (l_power > target)
l_power -= adjustby;
else if (r_power < target)
r_power += adjustby;
else if (l_power > 1)
l_power -= adjustby;
else
r_power += adjustby;
} else if (diff < 0) {
if (r_power > target)
r_power -= adjustby;
else if (l_power < target)
l_power += adjustby;
else if (r_power > 1)
r_power -= adjustby;
else
l_power += adjustby;
}
if (l_power > 7)
l_power = 7;
else if (l_power < 0)
l_power = 0;
if (r_power > 7)
r_power = 7;
else if (r_power < 0)
r_power = 0;
if (l_power == 0)
l_power = 1;
if (r_power == 0)
r_power = 1;
if ((SONAR <= 5) && (left_dir == 1) && (right_dir == 1)) {
SetOutput (LEFT_OUT, OUT_OFF);
SetOutput (RIGHT_OUT, OUT_OFF);
l_power = 0;
r_power = 0;
}
SetPower (LEFT_OUT, l_power);
SetPower (RIGHT_OUT, r_power);
olddiff = diff;
}
SetOutput (LEFT_OUT, OUT_OFF);
SetOutput (RIGHT_OUT, OUT_OFF);
}
void parse_packet() {
int on = packet_buffer[0];
int dir = packet_buffer[1];
int turn = packet_buffer[2];
switch (packet_buffer[0]) {
case GO:
left_out = OUT_ON;
right_out = OUT_ON;
break;
case STOP:
left_out = OUT_OFF;
right_out = OUT_OFF;
break;
}
switch (packet_buffer[2]) {
case 11: left_mult = -1;
right_mult = 1;
left_dir = (dir == FWD)? -1 : 1;
right_dir = (dir == FWD)? 1 : -1;
break;
case 10: left_mult = -2;
right_mult = 1;
left_dir = (dir == FWD)? -1 : 1;
right_dir = (dir == FWD)? 1 : -1;
break;
case 9: left_mult = 1;
right_mult = 0;
left_out = OUT_OFF;
left_dir = 1;
right_dir = (dir == FWD)? 1 : -1;
break;
case 8: left_mult = 2;
right_mult = 1;
left_dir = (dir == FWD)? 1 : -1;
right_dir = (dir == FWD)? 1 : -1;
break;
case 7: case 6:
case 5:
left_mult = 1;
right_mult = 1;
left_dir = (dir == FWD)? 1 : -1;
right_dir = (dir == FWD)? 1 : -1;
break;
case 4: left_mult = 1;
right_mult = 2;
left_dir = (dir == FWD)? 1 : -1;
right_dir = (dir == FWD)? 1 : -1;
break;
case 3: left_mult = 0;
right_mult = 1;
left_dir = (dir == FWD)? 1 : -1;
right_dir = 1;
right_out = OUT_OFF;
break;
case 2: left_mult = 1;
right_mult = -2;
left_dir = (dir == FWD)? 1 : -1;
right_dir = (dir == FWD)? -1 : 1;
break;
case 1: left_mult = 1;
right_mult = -1;
left_dir = (dir == FWD)? 1 : -1;
right_dir = (dir == FWD)? -1 : 1;
break;
}
ClearSensor (LEFT_ENC);
ClearSensor (RIGHT_ENC);
if (left_dir == 1)
SetDirection (LEFT_OUT, LEFT_FWD);
else
SetDirection (LEFT_OUT, LEFT_REV);
if (right_dir == 1)
SetDirection (RIGHT_OUT, RIGHT_FWD);
else
SetDirection (RIGHT_OUT, RIGHT_REV);
if (left_out == OUT_ON)
SetOutput (LEFT_OUT, OUT_ON);
else
SetOutput (LEFT_OUT, OUT_OFF);
if (right_out == OUT_ON)
SetOutput (RIGHT_OUT, OUT_ON);
else
SetOutput (RIGHT_OUT, OUT_OFF);
}
void wait_for_packet() {
int in_timeout = 0;
ClearTimer (PACKET_TIMER);
do {
ReadPacket();
if (error != 0 && error != NO_RSP) {
Wait(5);
PlaySound(SOUND_CLICK);
}
if (FastTimer(PACKET_TIMER) > 200 && !in_timeout) {
SetOutput (LEFT_OUT, OUT_OFF);
SetOutput (RIGHT_OUT, OUT_OFF);
PlaySound (SOUND_DOWN);
in_timeout = 1;
}
} while (!(error == 0 && packetlen == MAX_LENGTH));
Wait(5);
}
task main() {
SetSensor(LEFT_ENC, SENSOR_ROTATION);
SetSensor(RIGHT_ENC, SENSOR_ROTATION);
SetSensor(SONAR, SENSOR_LIGHT);
SetTxPower(TX_POWER_HI);
SetUserDisplay(packet_buffer[2], 0);
ClearSensor(LEFT_ENC);
ClearSensor(RIGHT_ENC);
start drive;
while (1) {
wait_for_packet();
parse_packet();
}
}