]> code.bitgloo.com Git - abelleisle/vex5106z.git/commitdiff
eh?
authorClyne Sullivan <tullivan99@gmail.com>
Mon, 16 Nov 2015 00:53:06 +0000 (19:53 -0500)
committerClyne Sullivan <tullivan99@gmail.com>
Mon, 16 Nov 2015 00:53:06 +0000 (19:53 -0500)
include/main.h
src/auto.c
src/auton.c [new file with mode: 0644]
src/init.c
src/opcontrol.c

index 6d369738aad189fee4f2ee74abf43c35fc240e58..d1fcdb4e479413b2061cc30671674f1190dbed4b 100644 (file)
@@ -30,12 +30,13 @@ enum MOTOR_PORT_MAP {
 };\r
 \r
 enum IME_PORT_MAP {\r
-       IDRIVER,\r
+       IDRIVER = 0,\r
        IDRIVEL,\r
        IROTATER,\r
        ILIFT1,\r
        ILIFT2,\r
-       ICANNON3\r
+       ICANNONL,\r
+       ICANNONR\r
 };\r
 \r
 \r
index 33204f9be4ee0cc164c9df100102e84e0cfa98e4..3c8f2ef3b382a95b3d2bf89cbf663a670ad2c303 100644 (file)
@@ -1,6 +1,6 @@
 #include <main.h>\r
 \r
-#define TARGET_RPM 1970\r
+#define TARGET_SPEED 65\r
 \r
 static unsigned int time;\r
 \r
@@ -10,37 +10,32 @@ void autoDelay(unsigned int ms){
 }\r
 \r
 void autonomous(){\r
-       static int    trpm;\r
-       static double rpm;\r
-       static char cs;\r
+       static char speed = 0;\r
 \r
        time = 15000;\r
-       cs = rpm = trpm = 0;\r
 \r
        do{\r
 \r
-               cs+=cs<100?10:0;\r
+               speed+=10;\r
 \r
-               motorSet(CANNON1,cs);\r
-               motorSet(CANNON2,cs);\r
-               motorSet(CANNON3,cs);\r
-               motorSet(CANNON4,cs);\r
+               motorSet(CANNON1,speed);\r
+               motorSet(CANNON2,speed);\r
+               motorSet(CANNON3,speed);\r
+               motorSet(CANNON4,speed);\r
 \r
-               autoDelay(800);\r
+               autoDelay(200);\r
 \r
-               imeGetVelocity(ICANNON3,&trpm);\r
-               rpm=abs(trpm)/24.5L;\r
-               rpm*=25.0L;\r
+       }while(speed<TARGET_SPEED);\r
 \r
-       }while(rpm<TARGET_RPM);\r
+       autoDelay(800);\r
 \r
-       motorSet(LIFT1,127);\r
-       motorSet(LIFT2,127);\r
+       motorSet(LIFT1 ,127);\r
+       motorSet(LIFT2 ,127);\r
+       motorSet(INTAKE,127);\r
 \r
+       //while(1);\r
        delay(time);\r
 \r
-       // Stop                                                                         4000ms remaining\r
-\r
        motorStopAll();\r
 \r
 }\r
diff --git a/src/auton.c b/src/auton.c
new file mode 100644 (file)
index 0000000..8af90eb
--- /dev/null
@@ -0,0 +1,153 @@
+#include <main.h>
+
+extern Gyro gyro;
+
+#ifndef PI
+#define PI 3.14159265L
+#endif // PI
+
+#define RPM_DEFAULT_MAX                160                             //      Max RPM of high-speed motor
+#define RPM_CANNON_MAX         4000                    //      Max RPM of cannon (motor + gears)
+#define RPM_CANNON_INC         31.49606299L    //      Expected change in RPM per joystick increment
+
+#define RPM_THRESHOLD          100                             //      A margin of error for matching the target RPM
+
+#define INC_FAULT                      2                               //      Boost given to motors when left and right don't match RPM
+#define INC_NORMAL                     2                               //      Used to match actual velocity to the target
+
+#define ROT_THRESHOLD          (PI/8)                  //      Margin of error for auto-aiming
+#define ROT_SPEED                      30                              //      How fast to rotate the cannon for aiming (for linear aiming only)
+
+static double rpmTarget = 0;   // Contains the desired RPM
+
+static double rpmCannL = 0;            // Left side's RPM
+static double rpmCannR = 0;            // Right side's RPM
+static double rpmCannA = 0;            // Average of the two above
+
+static double rotCannon = 0;   // Cumulative rotation of the cannon in radians
+
+/**
+ * Calculates RPMs from cannon motors.
+ *
+ * There are two IMEs on the cannon, one per each side. This function converts the raw
+ * velocity reading from the motors and converts it to rotations per minute (RPM).
+ * Results are stored in global variables defined above, as well as an average of the
+ * two.
+ */
+
+void cannUpdate(void){
+       int cl,cr,rc;
+
+       /*
+        *      Read raw velocity values.
+       */
+
+       imeGetVelocity(ICANNONL,&cl);
+       imeGetVelocity(ICANNONR,&cr);
+
+       /*
+        *      Divide by a divisor given in API.h and multiply the result by the cannon's gear ratio.
+       */
+
+       rpmCannL = cl / 24.5L * 25.0L;
+       rpmCannR = cr / 24.5L * 25.0L;
+
+       /*
+        *      Calculate an average of the two results from above.
+       */
+
+       rpmCannA = (rpmCannL + rpmCannR) / 2;
+
+       /*
+        *      Find the cumulative rotation of the cannon for auto-aiming.
+       */
+
+       imeGet(IROTATER,&rc);
+
+       rotCannon = rc / 627.2L * 5;
+       rotCannon *= 2*PI;                              // convert to radians
+
+}
+
+/**
+ * Sets a target RPM for the cannon.
+ *
+ * This calculates a target RPM by simply multiplying the current position of a jostick axis
+ * by a predetermined increment that is 1/127th of the highest possible RPM of the cannon.
+ *
+ * @param a value returned from a call to joystickGetAnalog()
+ */
+
+void cannTarget(char jpos){
+       rpmTarget = jpos * RPM_CANNON_INC;
+}
+
+/**
+ * Runs/Updates the actual speed of the cannon motors.
+ *
+ * Speeds for each side of the cannon are kept inside the scope of this function. Two checks
+ * are made before applying the motor speeds. The first one will increase the speed of one
+ * side of the cannon if the RPMs of the two sides aren't reasonably equal. The second check
+ * will bring the overall speeds up or down depending on where the actual average RPM is
+ * compared to the target. Following these checks is the setting of the motor speeds.
+ */
+
+void cannRun(void){
+       static char speedCannL = 0;
+       static char speedCannR = 0;
+
+       /*
+        *      Make sure cannon motors are up to about the same speed (as in RPM).
+       */
+
+                if(rpmCannR < rpmTarget + RPM_THRESHOLD && rpmCannL < rpmCannR - RPM_THRESHOLD) speedCannL += INC_FAULT;
+       else if(rpmCannL < rpmTarget + RPM_THRESHOLD && rpmCannR < rpmCannL - RPM_THRESHOLD) speedCannR += INC_FAULT;
+
+       /*
+        *      Adjust motor velocities to match the target.
+       */
+
+       if(rpmTarget > rpmCannA + RPM_THRESHOLD){
+               speedCannL += INC_NORMAL;
+               speedCannR += INC_NORMAL;
+       }else if(rpmTarget < rpmCannA - RPM_THRESHOLD){
+               speedCannL -= INC_NORMAL;
+               speedCannR -= INC_NORMAL;
+       }
+
+       /*
+        *      Apply the calculated motor speeds.
+       */
+
+       motorSet(CANNON1,speedCannL);
+       motorSet(CANNON2,speedCannR);
+       motorSet(CANNON3,speedCannL);
+       motorSet(CANNON4,speedCannR);
+}
+
+/**
+ * Aims the cannon towards a specified location(?)
+ *
+ * ... . Also sets the motor speed.
+ *
+ * @param a rotation to base calculations of off (preferably that of the robot's body)
+ */
+
+void cannAim(double r){
+       static char speed = 0;
+
+       /*
+        *      Do simple linear adjustments to have okay-ish aim. Once self-location is accomplished
+        *      a more accurate function could be used to adjust aim.
+       */
+
+                if(rotCannon > r + ROT_THRESHOLD) speed =  ROT_SPEED;
+       else if(rotCannon < r - ROT_THRESHOLD) speed = -ROT_SPEED;
+       else                                                               speed =  0;
+
+       /*
+        *      Apply the resulting speed to the motor.
+       */
+
+       motorSet(ROTATER,speed);
+}
index 3ffa429836a418795151195c0603af8703123772..a59dcba2405a8e17896b0fd9864d95bfd5b2d070 100644 (file)
@@ -6,6 +6,9 @@ unsigned int imeCount;
 void initializeIO(){\r
        pinMode(ANALOG_PORT(1),INPUT_ANALOG);   // Power expander status port\r
        pinMode(1,OUTPUT);                                              // LED\r
+       pinMode(2,INPUT);\r
+       pinMode(3,INPUT);\r
+       pinMode(4,INPUT);\r
 }\r
 \r
 void initialize(){\r
@@ -16,26 +19,14 @@ void initialize(){
        lcdClear(uart1);\r
        lcdSetBacklight(uart1,1);\r
 \r
-       lcdInit(uart2);\r
-       lcdClear(uart2);\r
-       lcdSetBacklight(uart2,1);\r
-\r
        //      Setup sensors.\r
 \r
        imeCount = imeInitializeAll();\r
        gyro=gyroInit(2,0);\r
 \r
        lcdPrint(uart1,1,"%u IMEs :)",imeCount);\r
-\r
-       lcdPrint(uart2,1,"ERR: Dark theme ");\r
-       lcdPrint(uart2,2,"     not found! ");\r
-\r
-       delay(2000);\r
-\r
+       delay(1000);\r
        lcdPrint(uart1,1,"ready...");\r
-       lcdPrint(uart2,1,"...yeah.        ");\r
-       lcdPrint(uart2,2,"                ");\r
-\r
        delay(1000);\r
 \r
 }\r
index d4d50a2cde262730906dd3f1769d63a6f6b36c20..8e410fa1b560d50aeb0ffe6cb48fc93b546fb2f1 100644 (file)
 #include <stdint.h>\r
 #include <math.h>\r
 \r
-extern Gyro gyro;      // Originally defined in init.c\r
-\r
-/*\r
- *     These keep track of the current LCD 'window' and the number of 'windows' that exist.\r
- */\r
-\r
-static   signed int ctty=0;\r
-const  unsigned int mtty=4;\r
-\r
-static double imeDriveLeft;\r
-static double imeDriveRight;\r
-static double imeRotater;\r
-\r
-static double gyroRotation;\r
-\r
-/*\r
- *     This runs as a separate task to update the LCD.\r
- */\r
-\r
-void operatorLCD(void *unused){\r
-       static int ime;\r
-\r
-       while(1){\r
-\r
-               /*\r
-                *      Display information according to the current 'window'.\r
-                */\r
-\r
-               switch(ctty){\r
-               default:\r
-\r
-               case 0: //      Welcome screen\r
-\r
-                       lcdSetText(uart1,1,"   JOHN  CENA   ");\r
-                       lcdPrint(uart1,2,"  ===========%3d",motorGet(CANNON1));\r
-                       break;\r
-\r
-               case 1: //      Battery levels in volts\r
-\r
-                       lcdPrint(uart1,1,"MAIN: %0.3f",(float)(powerLevelMain()/1000.0f));\r
-                       lcdPrint(uart1,2,"EXP : %0.3f",(float)(analogRead(1)   / 280.0f));\r
-                       break;\r
-\r
-               case 2: //      Gyroscope readings\r
-\r
-                       imeGet(IROTATER,&ime);\r
+#define PI 3.1415926535L\r
 \r
-                       double rot = ime / 3.0L / 627.2L * 10;\r
-\r
-                       rot = floor(rot) / 10;\r
-\r
-                       lcdPrint(uart1,1,"Gyro: %d",gyroGet(gyro));\r
-                       lcdPrint(uart1,2,"Rot.: %.1lf",rot);\r
-\r
-                       break;\r
+extern Gyro gyro;      // Originally defined in init.c\r
 \r
-               case 3:\r
+static double Vl,      // left wheel velocity\r
+                         Vr,   // right wheel velocity\r
+                         Vc,   // center/average velocity\r
+                         Va,   // angular velocity\r
+                         Vra;  // velocity ratio\r
 \r
-                       lcdPrint(uart1,1,"%.3lf",imeDriveLeft);\r
-                       lcdPrint(uart1,2,"%.3lf",imeDriveRight);\r
+static double R;       // radius of current circular path\r
 \r
-                       break;\r
-               }\r
+static double Px=0,    // X position\r
+                         Py=0; // Y position\r
 \r
-               delay(500);\r
-       }\r
-}\r
-\r
-void operatorPoll(){\r
-       static int idl,idr,ir,gr;\r
+void operatorLCD(void *start){\r
        while(1){\r
 \r
-               /*\r
-                *      Read in rotations of motors and the current angle of the robot.\r
-                */\r
-\r
-               imeGet(DRIVEL,&idl);                    // Get reading\r
-               imeDriveLeft  = idl / 627.0L;   // Convert to wheel rotations\r
-               imeDriveLeft *=  8.64L;                 // Convert to distance in inches\r
-\r
-               imeGet(DRIVER,&idr);                    // Get reading\r
-               imeDriveRight  = idr / 627.0L;  // Convert to wheel rotations\r
-               imeDriveRight *=  8.64L;                // Convert to distance in inches\r
-\r
-               imeGet(ROTATER,&ir);\r
-               imeRotater = ir / 627.0L;\r
-\r
-               gyroRotation = gyroGet(gyro);\r
+               lcdPrint(uart1,1,"%.3lf, %.3lf",R,Va);\r
 \r
                delay(100);\r
        }\r
 }\r
 \r
-void operatorControl(){\r
+static unsigned int START;\r
 \r
-       static bool selfAim = false;\r
+void operatorControl(){\r
 \r
        static char uiinc = 0;  // See below\r
+       static char in=0,lift;  // Used to set the multiple cannon motors to the same joy-stick reading.\r
 \r
-       static char in,lift;    // Used to set the multiple cannon motors to the same joy-stick reading.\r
+       static char joy;\r
 \r
-       taskCreate(operatorLCD ,TASK_DEFAULT_STACK_SIZE,NULL,TASK_PRIORITY_DEFAULT);\r
-       taskCreate(operatorPoll,TASK_DEFAULT_STACK_SIZE,NULL,TASK_PRIORITY_DEFAULT);\r
+       /*\r
+        *      Start other tasks.\r
+       */\r
+\r
+       START = ((!digitalRead(3)) | (!digitalRead(4)<<1)) + 1;\r
+       taskCreate(operatorLCD ,TASK_DEFAULT_STACK_SIZE,&START,TASK_PRIORITY_DEFAULT);\r
 \r
        while(1){\r
 \r
                //      Set the drive motors speeds.\r
 \r
-               motorSet(DRIVEL,joystickGetAnalog(1,3));\r
-               motorSet(DRIVER,joystickGetAnalog(1,2));\r
+               joy=joystickGetAnalog(1,3);\r
+               if(joy < 10 && joy > -10)joy=0;\r
+               motorSet(DRIVEL,joy);\r
+               joy=joystickGetAnalog(1,2);\r
+               if(joy < 10 && joy > -10)joy=0;\r
+               motorSet(DRIVER,joy);\r
 \r
                //      Set the rotating motor speed.\r
 \r
-               if(!selfAim){\r
-\r
-                       motorSet(ROTATER,-joystickGetAnalog(2,1)/2);\r
-\r
-               }else{\r
-\r
-                       //static int gc=0,gl=0;\r
-\r
-                       //gl = gc;\r
-                       //gc = gyroGet(gyro);\r
-\r
-               }\r
-\r
-               //      Set the cannon's speed.\r
+               motorSet(ROTATER,-joystickGetAnalog(2,1)/4);\r
 \r
                in=joystickGetAnalog(2,3);\r
 \r
@@ -140,14 +67,14 @@ void operatorControl(){
                // Set the intake's speed.\r
 \r
                motorSet(INTAKE,joystickGetDigital(1,6,JOY_UP  )?  127 :\r
-                               joystickGetDigital(1,6,JOY_DOWN)? -127 :\r
+                                               joystickGetDigital(1,6,JOY_DOWN)? -127 :\r
                                                0 );\r
 \r
                // Set the lift's speed.\r
 \r
                lift=joystickGetDigital(2,6,JOY_UP  )?  127 :\r
-                               joystickGetDigital(2,6,JOY_DOWN)? -127 :\r
-                                               0 ;\r
+                        joystickGetDigital(2,6,JOY_DOWN)? -127 :\r
+                        0 ;\r
 \r
                motorSet(LIFT1,lift);\r
                motorSet(LIFT2,lift);\r
@@ -159,130 +86,108 @@ void operatorControl(){
                if(++uiinc==20){        // Equates to every 200ms\r
                        uiinc=0;\r
 \r
-                       // Goto next 'window'.\r
-\r
-                       if(joystickGetDigital(1,7,JOY_UP) ||\r
-                                       joystickGetDigital(2,7,JOY_UP) ){\r
-                               if(++ctty==mtty)ctty=0;\r
-                       }\r
-\r
-                       // Goto previous 'window'.\r
-\r
-                       if(joystickGetDigital(1,7,JOY_DOWN) ||\r
-                                       joystickGetDigital(2,7,JOY_DOWN) ){\r
-                               if(--ctty==-1)ctty=mtty-1;\r
-                       }\r
-\r
                        // Run autonomous (for testing wo/ competition switch).\r
 \r
                        if(joystickGetDigital(1,7,JOY_RIGHT))\r
                                autonomous();\r
 \r
-                       // Goto test area.\r
+                       // Test\r
 \r
                        if(joystickGetDigital(1,7,JOY_LEFT)){\r
-                               static double target = 0;\r
 \r
-                               if(!target) target = (imeDriveLeft+imeDriveRight) / 2 + 13;\r
+                       }\r
 \r
-                               motorSet(DRIVEL,60);\r
-                               motorSet(DRIVER,60);\r
+               }\r
 \r
-                               while((imeDriveLeft+imeDriveRight) / 2 < target)\r
-                                       delay(10);\r
+               delay(10);      // Short delay to allow task switching\r
 \r
-                               motorSet(DRIVEL,0);\r
-                               motorSet(DRIVER,0);\r
+               /*\r
+                *      Get the velocity of the two (IME'd) drive motors.\r
+               */\r
 \r
-                       }\r
+               static int vl,vr;\r
 \r
-               }\r
+               imeGetVelocity(1,&vl);\r
+               imeGetVelocity(0,&vr);\r
 \r
-               delay(10);      // Short delay to allow task switching.\r
-       }\r
-}\r
+               /*\r
+                *      Convert the raw reading to rotations a minute, then inches per minute, then inches\r
+                *      per second.\r
+               */\r
 \r
+               Vl =  vl /* RPM Divisor         */ / 39.2L\r
+                                /* Wheel Circumference */ * 8\r
+                                /* Minutes to seconds  */ / 60;\r
 \r
-//Totally Theoretical PseudoCode for AutoShoot\r
-//Based on IME data:\r
-double lVel;//=velocity of left side\r
-double rVel;//=velocity of right side\r
-double cVel;//=velocity of center (calculated below)\r
-double aVel;//=angular velocity (calculated below)\r
+               Vr = -vr / 39.2L * 8 / 60;      // Right wheel IME is inverted\r
 \r
+               Vc = (Vl + Vr) / 2;                     // Average/Center velocity\r
 \r
-//Used to find rectangular vectors * double aVel=angular velocity of robot\r
-//Used to store the rectangular vectors:\r
-double xVel1;\r
-double xVel2;\r
-double yVel1;\r
-double yVel2;\r
+               /*\r
+                *      Round down the results to the nearest inch, and enforce a 2 in/s threshold.\r
+               */\r
 \r
+               Vl = floor(Vl);\r
+               Vr = floor(Vr);\r
 \r
-//Final Position Vectors, robot and target\r
-double xPos;\r
-double yPos;\r
-double xTarget;\r
-double yTarget;\r
+               if(Vl < 2 && Vl > -2) Vl = 0;\r
+               if(Vr < 2 && Vr > -2) Vr = 0;\r
 \r
+               /*\r
+                *      Calculate the ratio of the higher velocity to the lowest, for determining the\r
+                *      radius of the circle the robot is forming.\r
+               */\r
 \r
-//time difference variables\r
-double time1=0;\r
-double time2=0;\r
+               if(((!Vr) & (Vl!=0)) ||\r
+                  ((!Vl) & (Vr!=0)) ){\r
 \r
-int start;//1 is right blue, 2 is left blue, 3 is right blue, 4 is left blue\r
+                       /*\r
+                        *      One wheel isn't moving, the radius is the distance between the wheels.\r
+                       */\r
 \r
+                       R = 15;\r
+                       goto CONT;\r
 \r
-//Vector Assignments:\r
-void Vectors(){\r
-       if(start==1){xPos=37;yPos=138;xTarget=137;yTarget=7;}\r
-       if(start==2){xPos=13;yPos=114;xTarget=137;yTarget=7;}\r
-       if(start==3){xPos=37;yPos=13;xTarget=137;yTarget=137;}\r
-       if(start==4){xPos=13;yPos=37;xTarget=137;yTarget=137;}\r
-       while(1){//something in the brackets\r
+               }else if((Vr > Vl) & (Vl > 0) ||        // Curve to forwards right\r
+                                (Vl > Vr) & (Vl < 0) ){        // Curve to backwards right\r
 \r
-               imeGetVelocity(DRIVEL,&lVel);//get reading of left velocity\r
-               lVel=lVel/24.5*8.64;\r
+                       Vra = Vr / Vl;\r
 \r
-               imeGetVelocity(DRIVER,&rVel);//get reading of right velocity\r
-               rVel=rVel/24.5*8.64;\r
+               }else if((Vl > Vr) & (Vr > 0) ||        // Curve to forwards left\r
+                                (Vr > Vl) & (Vr < 0) ){        // Curve to backwards left\r
 \r
-               int i=0;//counter for use of alternating variables\r
-               i++;\r
-               if(i==1){//just used the first time\r
-                       time1=milis();\r
-               }\r
-               cVel=(lVel+rVel)/2;//calculates the (c)enter of the robot's velocity\r
+                       Vra = Vl / Vr;\r
 \r
-               if(lVel>rVel){\r
-                       aVel=cVel/(16*lVel/(rVel-lVel));\r
-               }\r
+               }else Vra = 0;                                          // No movement?\r
 \r
-               if(rVel>lVel){\r
-                       aVel=cVel/(16*rVel/(lVel-rVel));\r
-               }\r
+               if(Vra<0) Vra *= -1;                            // get absolute value of the ratio\r
 \r
-               else{\r
-                       aVel=0;\r
+               /*\r
+                *      "Plug-n'-chug" for a radius, assuming that the radius will increase by 7.5 (the\r
+                *      halfway between the wheels on the robot) when multiplied by the ratio.\r
+               */\r
 \r
-                       if(i%2==0){\r
-                               xVel1=cos(aVel)*cVel;//every 2 it uses these variables\r
-                               yVel1=sin(aVel)*cVel;\r
-                       }\r
+               for(R = 0; R < 200; R++){\r
 \r
-                       else{\r
-                               xVel2=cos(aVel)*cVel;//otherwise it uses these\r
-                               yVel2=sin(aVel)*cVel;\r
-                       }\r
+                       if(R * Vra > R + 7 &&           // Allow a one inch margin of error\r
+                          R * Vra < R + 8)break;       //\r
+               }\r
 \r
-                       time2=milis();//records the time before calculating\r
+CONT:\r
 \r
-                       xPos+=((xVel1+xVel2)/2)*(time2-time1);//finds the area of the x curve using trapezoidal approx.\r
-                       yPos+=((yVel1+yVel2)/2)*(time2-time1);//finds the area of the y curve using trapezoidal approx.\r
+               /*\r
+                *      Calculate the anglular velocity of the robot.\r
+               */\r
 \r
-                       delay(20);\r
-               }\r
-               time1=milis();//records time between calculations for next time\r
-       }//end of while\r
-}//end of Vectors\r
+               Va = Vc / R;\r
 \r
+               /*\r
+                *      Determine the increase in X and Y position based on the angular velocity and the\r
+                *      average total movement.\r
+               */\r
+\r
+               Px += cos(Va) * Vc * .01;       // Convert per second velocity to per 10ms, as the motors\r
+               Py += sin(Va) * Vc * .01;       // have only been at this velocity for that time (above).\r
+\r
+       }\r
+}\r