#include <stdint.h>\r
#include <math.h>\r
\r
+/**\r
+ * The distance in inches the robot starts from the goal.\r
+ */\r
+\r
#define GOAL_DISTANCE 120\r
\r
-/*\r
+/**\r
* RTTTL songs for speaker usage.\r
*/\r
\r
const char *bound = "Nobody to Love:d=4,o=5,b=125:4d#5,2g5,4p,4g5,4f5,2g5,4d#5,4f5,2g5,4d#5,4f5,4g5,4d#5,4d#5,4f5,4g5,4a#4,1c5,4d#5,4f5,2g5,\\r
4a#5,8g5,8f5,4d#5";\r
\r
-/*\r
- * Contains how many milliseconds it took to enter operatorControl().\r
+/**\r
+ * Contains how many milliseconds it took to enter operatorControl(), used to\r
+ * measure how long we've been in operatorControl().\r
*/\r
\r
static unsigned long opmillis = 0;\r
\r
-/*\r
- * Contains a light sensor value calculated at init time for object detection.\r
+/**\r
+ * Contains a light sensor value collected at init time for object detection.\r
*/\r
\r
static int lightThresh = 0;\r
\r
+/**\r
+ * The value passed to motorSet() for the cannons. This variable is declared\r
+ * in a global scope so that the 'Speed Adjust' buttons can modify raw speed\r
+ * when not in RPM Tracking Mode.\r
+ */\r
+\r
static char cann = 0;\r
-static double rpm = 0,trpm = 1750, arpm = 0;\r
+\r
+/**\r
+ * 'rpm' is the current RPM of the cannon motors when in RPM Tracking Mode.\r
+ * 'trpm' contains the target RPM for the cannon to reach, which is adjusted\r
+ * when the robot moves.\r
+ * 'arpm' stands for Adjust RPM, and contains a value modifiable by the\r
+ * operator and added to the target RPM.\r
+ */\r
+\r
+static double rpm = 0,\r
+ trpm = 1850,\r
+ arpm = 0;\r
+\r
+/**\r
+ * Contains the current X and Y position in inches. The X axis extends from\r
+ * the front of the robot, with the Y axis perpendicular to the X axis.\r
+ */\r
\r
static double xpos=0,ypos=0;\r
\r
+/**\r
+ * These bools are set by their corresponding tasks when those tasks are ran or\r
+ * stopped. These prevent multiple instances of the same task.\r
+ */\r
+\r
static bool cannonProcRun = false,\r
armProcRun = false,\r
aimProcRun = false;\r
\r
+/**\r
+ * Task handles for the tasks, should they be needed.\r
+ */\r
+\r
TaskHandle taskLCD,\r
taskCannon,\r
taskArm,\r
taskMove,\r
taskAim;\r
\r
+/**\r
+ * Task function prototypes so that they can be spawned from operatorControl().\r
+ */\r
+\r
void lcdUpdateFunc(void *);\r
void cannonProc(void *);\r
void armProc(void *);\r
* reset flags.\r
*/\r
\r
- AIRCR = (AIRCR & 0xFFFF) | (VECT_KEY << 16) | SYSRESETREQ | VECTRESET;\r
+ AIRCR = (AIRCR & 0xFFFF) | (VECTKEY << 16) | SYSRESETREQ | VECTRESET;\r
\r
// Update the AIRCR.\r
\r
******************************************************************************/\r
\r
void operatorControl(){\r
+\r
+ /**\r
+ * 'ui_inc' is used to have button reads happen at a certain interval.\r
+ * 'cyc' contains what song to play next off of the speaker.\r
+ */\r
+\r
static unsigned char ui_inc = 0;\r
static unsigned char cyc = 0;\r
+\r
+ /**\r
+ * The raw speed to set the lift motors to.\r
+ */\r
+\r
static char lift;\r
\r
+ /**\r
+ * Collected init-time variables.\r
+ */\r
+\r
opmillis = millis();\r
lightThresh = analogRead(8) - 60;\r
\r
+ /**\r
+ * Spawn the LCD task and the position-tracking task.\r
+ */\r
+\r
taskLCD=taskCreate(lcdUpdateFunc,TASK_DEFAULT_STACK_SIZE,NULL,TASK_PRIORITY_DEFAULT);\r
taskMove=taskCreate(moveProc,TASK_DEFAULT_STACK_SIZE,NULL,TASK_PRIORITY_DEFAULT+1);\r
\r
// Set the intake's speed.\r
\r
zMotorSet("Intake",\r
- zGetDigitalMotorSpeed(1,5,JOY_UP,JOY_DOWN,127),\r
+ zGetDigitalMotorSpeed(1,5,JOY_UP,JOY_DOWN,127)/*|\r
+ zGetDigitalMotorSpeed(2,5,JOY_UP,JOY_DOWN,127)*/,\r
0\r
);\r
\r
if(++ui_inc == 50){\r
ui_inc = 0;\r
\r
+ // 1-5 CPU reset\r
+\r
if(zJoyDigital(1,5,JOY_UP) && zJoyDigital(1,5,JOY_DOWN))\r
- cpu_reset();\r
+ softwareReset();\r
+\r
+ // 1-7L Speaker function\r
\r
- if(zJoyDigital(1,7,JOY_LEFT)){\r
+ /*if(zJoyDigital(1,7,JOY_LEFT)){\r
speakerInit();\r
switch(cyc){\r
case 0:speakerPlayRtttl(song );break;\r
}\r
if(++cyc == 4) cyc = 0;\r
speakerShutdown();\r
- }else if(zJoyDigital(1,7,JOY_RIGHT)){\r
+\r
+ // 2-8R Gyroscope reset\r
+\r
+ }else if(zJoyDigital(2,8,JOY_RIGHT)){\r
zGyroReset();\r
zMotorIMEReset("Rotater");\r
- }else if(zJoyDigital(1,7,JOY_UP))\r
+\r
+ // 2-8U Auto-Aim start\r
+\r
+ }else if(zJoyDigital(2,8,JOY_UP))\r
taskAim = taskCreate(aimProc,TASK_DEFAULT_STACK_SIZE,NULL,TASK_PRIORITY_DEFAULT);\r
- else if(zJoyDigital(1,7,JOY_DOWN))\r
- aimProcRun = false;\r
\r
- if(zJoyDigital(1,8,JOY_UP)){\r
+ // 2-8D Auto-Aim kill\r
+\r
+ else if(zJoyDigital(2,8,JOY_DOWN))\r
+ aimProcRun = false;*/\r
+\r
+ // 2-7U Increase cannon (speed/target RPM)\r
+\r
+ if(zJoyDigital(1,7,JOY_UP)){\r
if(cannonProcRun) arpm += 50;\r
else if(cann < 120)cann += 10;\r
- }else if(zJoyDigital(1,8,JOY_DOWN)){\r
+\r
+ // 2-7D Decrease cannon\r
+\r
+ }else if(zJoyDigital(1,7,JOY_DOWN)){\r
if(cannonProcRun) arpm -= 50;\r
else if(cann > -120)cann -= 10;\r
- }else if(zJoyDigital(1,8,JOY_LEFT)){\r
+\r
+ // 2-7L Toggle RPM Tracking task.\r
+\r
+ }else if(zJoyDigital(1,7,JOY_LEFT)){\r
if(!cannonProcRun)\r
taskCannon = taskCreate(cannonProc,TASK_DEFAULT_STACK_SIZE,NULL,TASK_PRIORITY_DEFAULT);\r
else\r
cannonProcRun = false;\r
}\r
\r
- if(zJoyDigital(1,8,JOY_RIGHT))\r
+ // 2-7R Start Ball Pusher task.\r
+\r
+ if(zJoyDigital(1,7,JOY_RIGHT))\r
taskArm = taskCreate(armProc,TASK_DEFAULT_STACK_SIZE,NULL,TASK_PRIORITY_DEFAULT);\r
}\r
\r
*/\r
\r
void moveProc(void *unused_param){\r
+\r
+ /**\r
+ * 'l' and 'r' contain IMEGet() values, 'lv' and 'rv' contain\r
+ * IMEGetVelocity() values.\r
+ */\r
+\r
static double l,r,lv,rv;\r
+\r
+ /**\r
+ * 'dist' might contain the total distance traveled in the past 10\r
+ * milliseconds.\r
+ * 'head' contains the angle the robot is facing at relative to its origin.\r
+ * 'dpos' is the delta position.?\r
+ */\r
+\r
static double dist,head;\r
static double dpos;\r
+\r
while(1){\r
\r
+ /**\r
+ * Get IMEGet values.\r
+ */\r
+\r
l = zMotorIMEGet("Left drive") / 627.2L;\r
r = -zMotorIMEGet("Right drive") / 627.2L;\r
\r
- // random # -> motor RPM -> wheel RPM (inches per minute) -> inches per millisecond\r
+ /**\r
+ * Get IMEGetVelocity values and convert to inches per millisecond:\r
+ *\r
+ * random # ->\r
+ * motor RPM ->\r
+ * wheel RPM (inches per minute) ->\r
+ * inches per millisecond\r
+ */\r
\r
lv = zMotorIMEGetVelocity("Left drive") / 39.2L * 8.64L / 60000;\r
rv = -zMotorIMEGetVelocity("Right drive") / 39.2L * 8.64L / 60000;\r
\r
- // total distance traveled since init\r
+ /**\r
+ * Get the distance thing.\r
+ */\r
+\r
dist = (l - r) * 8.64L;\r
\r
+ /**\r
+ * Calculate heading, then trash the result in favor of the gyroscope.\r
+ */\r
+\r
head = fmod(dist / 15,360.0L) / 2 * 90;\r
head = /*(head +*/ zGyroGet()/*) / 2*/;\r
\r
+ /**\r
+ * Calculate the delta position thing.\r
+ */\r
+\r
dpos = (lv+rv) / 2 * 20;\r
dpos *= 1000;\r
dpos = floor(dpos) / 1000;\r
\r
+ // Adjust position values.\r
+\r
ypos += sin(head * PI / 180) * dpos;\r
xpos += cos(head * PI / 180) * dpos;\r
\r
- //lcdPrint(uart1,1,"%.3lf,%.3lf",xpos,ypos);\r
-\r
delay(20);\r
}\r
}\r
*/\r
\r
void aimProc(void *procPtr){\r
+\r
static double cangle, // Current angle (of rotater)\r
- rangle, // 'Robot' angle (target angle\r
- angle; // Angle between x-axis and line from robot to goal\r
- static double dist; // Distance of robot from goal\r
- double xpos2,goal2;\r
+ rangle; // 'Robot' angle (target angle\r
+\r
+ // Tell others we're running.\r
\r
aimProcRun = true;\r
\r
- /*\r
- * Claim necessary motors.\r
+ /**\r
+ * Claim necessary motors to prevent others from using them.\r
*/\r
\r
zMotorTake("Rotater",1);\r
\r
- /*\r
+ /**\r
* Run until a stop is requested.\r
*/\r
\r
while(aimProcRun){\r
\r
- /*\r
+ /**\r
* Read orientation sensors.\r
*/\r
\r
cangle = (int)floor(zMotorIMEGet("Rotater") / 627.2L * 112.5);\r
- rangle = zGyroGet();\r
-\r
- xpos2 = pow(xpos,2);\r
- goal2 = pow(GOAL_DISTANCE - ypos,2);\r
- dist = sqrt(xpos2 + goal2);\r
- angle = acos((xpos2 + pow(dist,2) - goal2) / (2 * xpos * dist));\r
- rangle = (angle - PI / 2) * 180 / PI;\r
+ rangle = zGyroGet() - (atan(ypos / (GOAL_DISTANCE - xpos)) * 180 / PI);\r
\r
- lcdPrint(uart1,2,"%lf",angle);\r
+ lcdPrint(uart1,1,"%.3lf, %.3lf",cangle,rangle);\r
\r
- /*\r
+ /**\r
* Adjust aim if necessary.\r
*/\r
\r
delay(100);\r
}\r
\r
- /*\r
+ /**\r
* Free motors.\r
*/\r
\r
do{\r
\r
/*\r
- * Bring up the speed, --exiting if we go too high.-- (crossed out)\r
+ * Bring up the speed ...\r
* The only reasonable explanation for an error such as the speed\r
* getting too high is a hardware fault in the robot (bad motor,\r
* bad IME, ...).\r
*/\r
\r
- speed += 5;\r
+ speed += 10;\r
if(speed > 120)\r
speed = 127;\r
\r
zMotorSet("Left cannon" ,-speed,2);\r
zMotorSet("Right cannon", speed,2);\r
\r
- delay(400);\r
+ delay(300);\r
\r
/*\r
* Calculate the average RPM, and continue if our target is met.\r
\r
cl = zMotorIMEGetVelocity("Left cannon") / 16.3333125L * 9;\r
cr = -zMotorIMEGetVelocity("Right cannon") / 16.3333125L * 9;\r
- ca = /*(cl +*/ cr/*) / 2*/;\r
- rpm = ca;\r
-\r
- lcdPrint(uart1,2,"%.3lf/%.3lf",cl,cr);\r
+ rpm = ca = cr;//(cl + cr) / 2;\r
\r
}while(cannonProcRun && ca < trpm);\r
\r
\r
cl = zMotorIMEGetVelocity("Left cannon") / 16.3333125L * 9;\r
cr = -zMotorIMEGetVelocity("Right cannon") / 16.3333125L * 9;\r
- ca = /*(cl +*/ cr/*) / 2*/;\r
- rpm = ca;\r
+ rpm = ca = cr;//(cl + cr) / 2;\r
\r
/*\r
* Guess an RPM.\r
*/\r
\r
if(ca < trpm - 40){\r
- speed++;\r
+ speed += 2;\r
zMotorSet("Left cannon" ,-speed,2);\r
zMotorSet("Right cannon", speed,2);\r
- }else if(ca > trpm + 50){\r
- speed--;\r
+ }else if(ca > trpm + 40){\r
+ speed -= 2;\r
zMotorSet("Left cannon" ,-speed,2);\r
zMotorSet("Right cannon", speed,2);\r
}\r
\r
- lcdPrint(uart1,2,"%4.0lf/%4.0lf",trpm,rpm);\r
+ lcdPrint(uart1,2,"%.0lf|%.3lf\n",trpm,rpm);\r
+ //printf("%.0lf,%.3lf,%d\n",trpm,rpm,speed);\r
\r
- delay(200);\r
+ delay(100);\r
}\r
\r
zMotorSet("Left cannon" ,0,2);\r
* Just run the pusher if it was requested by the user.\r
*/\r
\r
- if(zJoyDigital(1,7,JOY_DOWN))\r
+ if(zJoyDigital(1,8,JOY_DOWN))\r
goto PUSH;\r
\r
/*\r
PUSH:\r
\r
zMotorSet("Misc",127,3);\r
- delay(1000);\r
+ delay(500);\r
zMotorSet("Misc",-127,3);\r
- delay(1000);\r
+ delay(500);\r
zMotorSet("Misc",0,3);\r
\r
/*\r
* Track elapsed time since operatorControl() entrance.\r
*/\r
\r
- elapsed = millis() - opmillis;\r
- lcdPrint(uart1,1,"%02d:%02d",(int)(elapsed / 60000),(int)((elapsed / 1000) % 60));\r
+ //elapsed = millis() - opmillis;\r
+ //lcdPrint(uart1,1,"%02d:%02d",(int)(elapsed / 60000),(int)((elapsed / 1000) % 60));\r
+ //lcdPrint(uart1,1,"%.3lf V",(float)analogRead(1)/70/4);\r
\r
+ //lcdPrint(uart1,2,"%4.0lf/%4.0lf",trpm,rpm);\r
delay(LCD_RATE);\r
}\r
}\r