different autonomous programs depending on start positition
| Author |
Message |
|
Roboram1
Rookie
Joined: Sun Sep 28, 2008 6:09 pm Posts: 4
|
 different autonomous programs depending on start positition
During software inspection, the autonomous program is checked to make sure it works. Can more than one autonomous program be used during the competition, depending where your robots starting position is?
|
| Tue Feb 17, 2009 5:40 pm |
|
 |
|
Sunny1261
Novice
Joined: Thu Oct 09, 2008 7:58 pm Posts: 79
|
 Re: different autonomous programs depending on start positition
I would guess, YES.
|
| Tue Feb 17, 2009 6:19 pm |
|
 |
|
Atlantisbase
Expert
Joined: Tue Oct 14, 2008 7:16 pm Posts: 171 Location: Investigating an unidentified ship sighted in Sector 31428
|
 Re: different autonomous programs depending on start positition
Since there is nothing that says you can't (unless someone has read something I haven't), although really what you need is a single branched Autonomus program that tests at the beginning what part to run. What you need to do then is create a series of flags that can be set before your bot goes on the field; we're using three touch sensors, this can ultimately allow for seven different autonomus programs. This works the binary number system where each increasing place value is doubled rather than times 10 and each place can only be 1 or 0. Thus, - 000 = 0
- 001 = 1
- 010 = 2
- 011 = 3
- 100 = 4
- 101 = 5
- 110 = 6
- 111 = 7
You can use a function like this to test for which are pressed; my set up for the sensors is a little funky but basically it tests for each possible combination and returns the decimal equivilent of that binary sequence. Please note that touchMXPVal[] is an array I have created in my program to hold the values returned from our Touch Multiplexer; it is constantly updated by a seperate task. I call this function from a switch statement and place the desired Autonomus code within each case statement, like so, You could also, theoretically place all the code for any given sequence inside a seperate function and call the appropriate function from each case statement or even from the previous testAuto() function rather than returning a value, this is an idea I have been toying with but have yet to get a chance to experiment with for various reasons. Mind you all of this assumes that you have the availble ports and sensors. If you couldn't do this, you could set up several different independent programs that you could pick and choose from but the FMS might not like that, nor the software inspectors.
_________________Captain, Head programmer, School of the Arts, Silverbots Robtics Team #2890
|
| Wed Feb 18, 2009 12:36 am |
|
 |
|
10nisman94
Novice
Joined: Mon Oct 13, 2008 6:29 pm Posts: 75 Location: Florida, USA
|
 Re: different autonomous programs depending on start positition
we have 5 programs 1 tele op and 1 for each starting position. No problems after three competitions.
_________________ PHUHS Robotics Team 516 FTW
Daytona Robofest Winning Alliance Captain Daytona Robofest Inspire Award
|
| Wed Feb 18, 2009 4:47 pm |
|
 |
|
Atlantisbase
Expert
Joined: Tue Oct 14, 2008 7:16 pm Posts: 171 Location: Investigating an unidentified ship sighted in Sector 31428
|
 Re: different autonomous programs depending on start positition
I have to say, I'm really not a fan of the split file structure, I rather like the single package model.
_________________Captain, Head programmer, School of the Arts, Silverbots Robtics Team #2890
|
| Wed Feb 18, 2009 5:24 pm |
|
 |
|
chadgeorge
Novice
Joined: Fri Oct 24, 2008 8:58 am Posts: 87
|
 Re: different autonomous programs depending on start positition
You only need one autonomous program. If you have more than 1 file in your program, I think keeping multiple versions of a program is too difficult to manage correctly. I wrote a user interface that allows selecting autonomous parameters from a menu. Red vs Blue On field vs Off Field Target racks, etc Also we save and load these parameters from a file every time the robot starts up. So you can set them before putting the robot on the field. Here's the code that makes this happen param.c  |  |  |  | Code: #if !(defined(CTYPES_H)) #include "ctypes.h" #endif
#define USE_ASSERT_ON_READ 0 // Check IO result after every read command #define USE_ASSERT_ON_WRITE 0 // Check IO result after every write command
typedef enum { kNearWall = 0, // Wall closest to the drivers kFarWall = 1, // Wall opposite to the drivers kRampWall = 2, // Wall in the direction of the ramp kOtherWall = 3 // Wall closest to the other drivers } TWallPos;
typedef enum { kAutoTeam = 0, // Automatically select start team kRedTeam = 1, kBlueTeam = 2, kSameTeam = 3, // Same as alliance team color kOtherTeam = 4 // Opposite from alliance team color } TTeamColor;
typedef enum { kStartOffField = 0, // Start on the Ramp kStartOnField = 1 // Start on the Field } TStartPosition;
typedef enum { kDumpNone = 0, // Don't dump racks kDumpEach = 1, // Dump the bucket before getting next rack kDumpAll = 2 // Get all racks before dumping } TDumpMode;
typedef enum { kKeepRack = 0, // Empty the rack and keep the pucks kDropRack = 1, // Empty the rack and discard pucks kWaitRack = 2 // Prepare to empty the rack, but wait } TRackMode;
typedef struct { TWallPos wall; // Which wall the target rack is on TTeamColor color; // Which color the target TRackMode mode; // Which action to take at the target } TAutoTarget;
typedef struct { int16 rack_down; int16 rack_ready; int16 dump_ready; int16 dump_full; } TArmTarget;
#define MAX_TARGETS 4 #define MAX_PARAM_SIZE 64
typedef struct { int16 n; // Numerator int16 d; // Denominator } TFraction;
#define MultFract(number, factor) number *= factor.n; number /= factor.d #define DivFract(number,factor) number *= factor.d; number /= factor.n
typedef union { struct { // Converts encoder ticks to 1/10in TFraction encoder_factor;
// Converts wheel ground speed to wheel rotation speed TFraction left_wheel_factor; TFraction right_wheel_factor;
// Convert desired wheel rotation speed to % motor power TFraction power_factor;
// Conversion factor for kinematics equation TFraction body_width;
// Angle offset from robot starting location int16 gyro_zero;
// Calibration factor for full 360 degree rotation TFraction gyro_cal;
TArmTarget arm_target;
// Autonomous Mode Parameters
TTeamColor team_color; // Team Color: Red, Blue, Auto TStartPosition start_pos; // Starting position OnField vs OffField TDumpMode dump_mode; // How to handle pucks after clear rack int16 prog_num; // Index of program that has been selected int16 num_targets; // Number of targets in the program TAutoTarget target1; // Rack Target information TAutoTarget target2; TAutoTarget target3; TAutoTarget target4; };
int16 data[MAX_PARAM_SIZE]; } TRobotParam;
#if USE_ASSERT_ON_READ #define ReadInt16(file, result,variable) ReadShort(file, result, variable); if(result) goto ReadErr #else #define ReadInt16(file, result,variable) ReadShort(file, result, variable) #endif
#define ReadTypecast(file, result, variable, typecast, temp) ReadInt16(file,result,temp); variable = (typecast)temp
#if USE_ASSERT_ON_WRITE #define WriteInt16(file, result,variable) WriteShort(file, result, variable); if(result) goto WriteErr #else #define WriteInt16(file, result,variable) WriteShort(file, result, variable) #endif
void SetDefaultParam(TRobotParam ¶m) { int i;
// First zero everything out for (i=0;i<MAX_PARAM_SIZE;i++) { param.data[i] = 0; }
param.left_wheel_factor.n = 360; // 360 degrees / rotation param.left_wheel_factor.d = 94; // left wheel diameter in 1/10 in = 3.1416 * 3 * 10
param.right_wheel_factor.n = 360; // 360 degrees / rotation param.right_wheel_factor.d = 92; // right wheel diameter in 1/10 in = 3.1416 * 3 * 10
param.power_factor.n = 100; // 100% power param.power_factor.d = 766; // 760 deg/sec (~20 in/sec) = 20 * 10 * 360 / 94
param.body_width.n = 283; // pi * radius of robot (between wheels) in 1/10 in = 9.0 * 3.1416 * 10.0 param.body_width.d = 180; // 180 (degrees to radians)
param.encoder_factor.n = 360; param.encoder_factor.d = 5506;
param.gyro_zero = 0; param.gyro_cal.n = 1; param.gyro_cal.d = 1;
param.arm_target.rack_down = 20; // Clear Rack Down Position param.arm_target.rack_ready = 45; // Clear Rack Ready Position param.arm_target.dump_ready = 85; // Dump Bucket Ready Position param.arm_target.dump_full = 145; // Dump Bucket Full Position
param.start_pos = kStartOnField; param.team_color = kAutoTeam; param.dump_mode = kDumpAll;
param.num_targets = 1; param.prog_num = 1; param.target1.wall = kNearWall; param.target1.color = kSameTeam; param.target1.mode = kKeepRack; }
bool WriteParamFile(TRobotParam ¶m, const string &sFileName ) { int i; int chksum = 0; int nParamFileSize = (MAX_PARAM_SIZE + 1) * 2;
TFileHandle hFile; TFileIOResult nResult;
Delete(sFileName, nResult); OpenWrite(hFile, nResult, sFileName, nParamFileSize);
if (nResult == ioRsltSuccess) { for (i=0;i<MAX_PARAM_SIZE;i++) { WriteInt16(hFile, nResult, param.data[i]); chksum += param.data[i]; } }
// Write the checksum at the end of the file WriteShort(hFile, nResult, chksum);
Close(hFile, nResult); return true;
WriteErr: Close(hFile, nResult); return false; }
bool ReadParamFile(TRobotParam ¶m, const string &sFileName) { int i,j; int chksum = 0;
TFileHandle hFile; TFileIOResult nResult; int nParamFileSize = (MAX_PARAM_SIZE + 1) * 2;
OpenRead(hFile, nResult, sFileName, nParamFileSize);
if (nResult == ioRsltSuccess) { for (i=0;i<MAX_PARAM_SIZE;i++) { ReadInt16(hFile, nResult, param.data[i]); chksum += param.data[i]; } }
// Verify checksum correct ReadShort(hFile, nResult, j); if (j != chksum) goto ReadErr;
Close(hFile, nResult); return true;
ReadErr: Close(hFile, nResult); return false; }
|  |  |  |  |
This saves and loads a set of parameters to the NXT as a file. The code only uses a checksum so version control isn't perfect. It'll usually detect a major change to the structure of the parameter file (ie you add a new parameter or delete one). It won't load a bad parameter set (instead you should load the default values in your code. If in doubt just delete the old parameter file and try again. here's a snippet of my code that uses the above routines.  |  |  |  | Code: #pragma autoStartTasks // Automatically start this task when the main user program starts.
#if !defined(GLOBALS_H) #include "globals.h" #endif
typedef enum { screenNone = 0, screenDiagnostics = 1, screenAutoSettings = 2 } TMenuScreen;
#define PlayAcceptSound() if (bSoundEnabled) PlaySound(soundBlip) #define PlayRejectSound() if (bSoundEnabled) PlaySound(soundShortBlip)
// Function Prototypes void displayPageHandler(int minPageNo, int maxPageNo, bool bWrapPages, TMenuScreen exitScreen); void showDiagnostics(); void showAutoSettings();
// Global variables used by this task
string sTelopFileName; // stores the name of the currently assign telop program TMenuScreen currScreen; // the name of the active screen TMenuScreen nextScreen; // the name of the next screen that should become active TButtons lastNxtButton; // a temporary variable to detect button transitions TButtons nxtBtnClick; // a variable assigned whenever a button is pressed int nDisplayLoopCounter; // counts the number of 100msec intervals between screen updates int nDisplayRefreshRate; // sets the rate at which the screen is updated int nScreenPage; // tracks the currently active page (for multi-page screens) int nCursorPos; // tracks the edit cursor position (for menus and edit boxes)
bool bDisplayEnabled = true; // Set to false in user program to disable diagnostic display bool bSoundEnabled = true; // Set to false to display user interface reposnse sounds.
/*********************************************** * Display Task - Event Handlers * - displayOnChange() * - displayOnKey() * - displayOnUpdate() */
// Called when a screen change occurs void displayOnChange() { eraseDisplay();
switch(nextScreen) { case screenDiagnostics: getUserControlProgram(sTelopFileName); break; case screenAutoSettings: nScreenPage = 0; nCursorPos = 0; break; } }
// Periodically called to update the current screen's contents void displayOnUpdate() { switch(currScreen) { case screenDiagnostics: showDiagnostics(); break; case screenAutoSettings: showAutoSettings(); break; } }
void displayTargetInfo(TAutoTarget &target, int index) { int j = 45-(index*9);
nxtDisplayStringAt(0, j, "%d", index + 1);
nxtDisplayStringAt(8, j, (target.wall == kNearWall ? "Near" : target.wall == kFarWall ? "Far" : target.wall == kRampWall ? "Ramp" : target.wall == kOtherWall ? "Other" : "ERR"));
nxtDisplayStringAt(39, j, (target.color == kRedTeam? "Red" : target.color == kBlueTeam ? "Blue" : target.color == kSameTeam ? "Same" : target.color == kOtherTeam ? "Other" : "ERR"));
nxtDisplayStringAt(71, j, (target.mode == kKeepRack? "Keep" : target.mode == kDropRack ? "Drop" : target.mode == kWaitRack ? "Wait" : "ERR"));
}
// Called whenever an NXT button has been pressed void displayOnKeyDown() { switch(currScreen) { case screenDiagnostics: if (nxtBtnClick == kEnterButton) nextScreen = screenAutoSettings; break;
case screenAutoSettings: if (nxtBtnClick == kEnterButton) { switch(nScreenPage) { // Change Team Color case 0: robot.param.team_color = (TTeamColor) ( ((int)robot.param.team_color + 1) % 3 ); PlayAcceptSound(); break;
// Change Start Position case 1: robot.param.start_pos = (TStartPosition) ( ((int)robot.param.start_pos+ 1) % 2 ); PlayAcceptSound(); break;
// Change Program Number case 2: robot.param.prog_num = (robot.param.prog_num + 1) % 3; switch(robot.param.prog_num) { case 0: robot.param.num_targets = 0; break; case 1: robot.param.num_targets = 1; robot.param.target1.wall = kNearWall; robot.param.target1.color = kSameTeam; robot.param.target1.mode = kKeepRack; break;
case 2: robot.param.num_targets = 2; robot.param.target1.wall = kNearWall; robot.param.target1.color = kSameTeam; robot.param.target1.mode = kKeepRack;
robot.param.target2.wall = kRampWall; robot.param.target2.color = kSameTeam; robot.param.target2.mode = kKeepRack; break;
} PlayAcceptSound(); break;
// Change Dump Mode case 3: robot.param.dump_mode = (TDumpMode) (((int)robot.param.dump_mode+1) % 3); PlayAcceptSound(); break;
// Program Summary and Save case 4: saveParam();
break; } } else { displayPageHandler(0,4,false,screenDiagnostics); eraseDisplay(); } break; } }
/*********************************************** * User Routines to draw screens * */
void showAutoSettings() { string stemp; int i,j;
switch (nScreenPage) { case 0: nxtDisplayCenteredTextLine(1, "Select Team");
nxtDisplayCenteredBigTextLine(4, (robot.param.team_color == kRedTeam ? "Red" : robot.param.team_color == kBlueTeam ? "Blue" : robot.param.team_color == kAutoTeam ? "Auto" : "ERR")); break;
case 1: nxtDisplayCenteredTextLine(1, "Select Position");
nxtDisplayCenteredBigTextLine(3, (robot.param.start_pos == kStartOnField ? "On" : robot.param.start_pos == kStartOffField ? "Off" : "ERR"));
nxtDisplayCenteredBigTextLine(5, "Field");
break;
case 2: nxtDisplayCenteredTextLine(1, "Select Program"); nxtDisplayCenteredBigTextLine(4, "%d", robot.param.prog_num);
nxtDisplayCenteredTextLine(6, ( robot.param.prog_num == 0 ? "Do Nothing" : robot.param.prog_num == 1 ? "Near & Dump" : robot.param.prog_num == 2 ? "Near + Ramp" :
"Unknown Program")); nxtDisplayCenteredTextLine(7, ( robot.param.prog_num == 2 ? "& Dump" : "")); break;
case 3: nxtDisplayCenteredTextLine(1, "Select Dump Mode"); nxtDisplayCenteredBigTextLine(4, (robot.param.dump_mode == kDumpNone ? "None" : robot.param.dump_mode == kDumpEach ? "Each" : robot.param.dump_mode == kDumpAll ? "All": "ERR"));
nxtDisplayCenteredTextLine(6, (robot.param.dump_mode == kDumpNone ? "Don't dump racks" : robot.param.dump_mode == kDumpEach ? "Dump after each" : robot.param.dump_mode == kDumpAll ? "Dump after all": "")); nxtDisplayCenteredTextLine(7, (robot.param.dump_mode == kDumpNone ? "" : robot.param.dump_mode == kDumpEach ? "rack cleared" : robot.param.dump_mode == kDumpAll ? "racks cleared": "")); break; case 4:
nxtDisplayStringAt(8, 56, "Rack"); nxtDisplayStringAt(38, 56, "Color"); nxtDisplayStringAt(71, 56, "Mode"); nxtDrawLine(0,47,100,47);
if(robot.param.num_targets > 0) displayTargetInfo(robot.param.target1, 0); if(robot.param.num_targets > 1) displayTargetInfo(robot.param.target2, 1); if(robot.param.num_targets > 2) displayTargetInfo(robot.param.target1, 2); if(robot.param.num_targets > 3) displayTargetInfo(robot.param.target1, 3);
nxtDisplayCenteredTextLine(7, "Enter to Save"); break; } }
void showDiagnostics() { getJoystickSettings(joystick); //Update variables with current joystick values
if (joystick.StopPgm) nxtDisplayCenteredTextLine(1, "Wait for Start"); else if (joystick.UserMode) nxtDisplayCenteredTextLine(1, "TeleOp Running"); else nxtDisplayCenteredTextLine(1, "Auton Running");
if ( externalBatteryAvg < 0) nxtDisplayTextLine(3, "Ext Batt: OFF"); //External battery is off or not connected else nxtDisplayTextLine(3, "Ext Batt:%4.1f V", externalBatteryAvg / (float) 1000);
nxtDisplayTextLine(4, "NXT Batt:%4.1f V", nAvgBatteryLevel / (float) 1000); // Display NXT Battery Voltage
nxtDisplayTextLine(5, "FMS Msgs: %d", nMessageCount); // Display Count of FMS messages
nxtDisplayTextLine(6, "Teleop FileName:"); nxtDisplayTextLine(7, sTelopFileName); }
/*********************************************** * Display Task - Common User Interface Routines * - displayPageHandler() */
// A generic handler for sets of pages: // Left - Move to previous page // Right - Move to the next page // Exit - Return to previous menu/screen
void displayPageHandler(int minPageNo, int maxPageNo, bool bWrapPages, TMenuScreen exitScreen) { switch(nxtBtnClick) { case kExitButton: if (exitScreen != screenNone) nextScreen = screenDiagnostics; break;
case kLeftButton: nScreenPage -= 1; if (nScreenPage < minPageNo) { if (bWrapPages) { PlayAcceptSound(); nScreenPage = maxPageNo; } else { PlayRejectSound(); nScreenPage = minPageNo; } } else { PlayAcceptSound(); } break;
case kRightButton: nScreenPage += 1; if (nScreenPage > maxPageNo) { if (bWrapPages) { PlayAcceptSound(); nScreenPage = minPageNo; } else { PlayRejectSound(); nScreenPage = maxPageNo; } } else { PlayAcceptSound(); } break; } }
/*********************************************** * Display Task - Application Interface Functions * - displayRefreshScreen() * - displayChangeScreen() * - displayDisable() * - displayEnable() */
void displaySetRefreshRate(int refreshRate) {
}
void displayDisable() { bDisplayEnabled = false; // Disable any drawing to the screen }
void displayEnable() { bDisplayEnabled = true; }
// forces the current screen to be reloaded void displayRefreshScreen() { bDisplayEnabled = false;
nextScreen = currScreen; currScreen = screenNone; nDisplayLoopCounter = 0;
bDisplayEnabled = true; }
// call to change the currently active screen void displayChangeScreen(TMenuScreen screen) { bDisplayEnabled = false;
nextScreen = screen; nDisplayLoopCounter = 0;
bDisplayEnabled = true; }
/*********************************************** * Display Task - Driver * * The display task allows simple implementation of * custom user interfaces and diagnostic screens on the NXT. * * By implementing a few event handlers a user interface can be * created that runs independent of the main application. */
task displayTask() {
bNxtLCDStatusDisplay = true; // Show the normal top status line nNxtExitClicks = 2; // Require 2 clicks to exit a program
nextScreen = screenDiagnostics; // Initial screen currScreen = screenNone;
nDisplayLoopCounter = 0; nDisplayRefreshRate = 4; // Number of 100 msec intervals between refreshes nScreenPage = 0; nCursorPos = 0;
while (true) { // Update the display for the currently active screen if (bDisplayEnabled && nDisplayLoopCounter <= 0) { nDisplayLoopCounter = nDisplayRefreshRate;
if (nextScreen != currScreen) { displayOnChange(); currScreen = nextScreen; }
displayOnUpdate(); }
if ((lastNxtButton != nNxtButtonPressed) && (nNxtButtonPressed != kNoButton)) nxtBtnClick = nNxtButtonPressed; lastNxtButton = nNxtButtonPressed;
if (nxtBtnClick != kNoButton) { // Process the key press displayOnKeyDown();
// Wait for the button to be released. while(nNxtButtonPressed != kNoButton); nxtBtnClick = (TButtons)kNoButton;
// Immediately update the screen nDisplayLoopCounter = 0; } else { wait1Msec(100); // allow the button handling code to run faster nDisplayLoopCounter -= 1; // than the display code to provide better user response } } }
|  |  |  |  |
This starts a task to run the user interface code. It overwrites (and replicates) some of what they are doing in JoystickDriver.c (which was a stupid place to put user interface code in my opinion) This menu/display code probably won't run "out-of-the-box" since I ripped it out of my project, but it'll get you going in the right direction if you make changes to the appropriate places.
|
| Wed Feb 18, 2009 5:39 pm |
|
 |
|
RogueRobotics
Rookie
Joined: Sat Oct 25, 2008 3:04 pm Posts: 5
|
 Re: different autonomous programs depending on start positition
We had almost the same setup as 10nisman94: 4 different autonomous programs, each with the Teleop part in the same file (when teams were using Exploding Bacon's template file).
|
| Thu Feb 19, 2009 3:40 am |
|
 |
|
10nisman94
Novice
Joined: Mon Oct 13, 2008 6:29 pm Posts: 75 Location: Florida, USA
|
 Re: different autonomous programs depending on start positition
unfortuately, this is no longer "allowed" the new joystick driver doesnt even check auto v tele just enable v disable, this is why the auto and tele templates are manditory
_________________ PHUHS Robotics Team 516 FTW
Daytona Robofest Winning Alliance Captain Daytona Robofest Inspire Award
|
| Thu Feb 19, 2009 5:41 pm |
|
 |
|
chadgeorge
Novice
Joined: Fri Oct 24, 2008 8:58 am Posts: 87
|
 Re: different autonomous programs depending on start positition
I disagree. There is nothing that prevents using the same program for autonomous and tele-op. Just check for auto vs manual yourself after the template's wait-for-enable code. Its definitely still in the joystick data packet.
Disclaimer: this is just my interpretation of the rules...your mileage may vary
Look at the software inspection checklist. Its 100% functional - 0% implementation specific. I see no checks on how the code is written, just what it is supposed to do. How you get there isn't critical. The templates just get you there one way. No where on the checklist does it tell a judge to even look at or ask about your code.
Now I had someone at FIRST call me to remind me to use two files. When I asked why they told me people thought the FMS was screwing up launching the same filename for auto and manual. Which would be a legit reason not to do this, but I didn't have any problems at my last event. I think those making that complaint screwed something up (probably by having different programs and not using the program chooser correctly).
|
| Thu Feb 19, 2009 6:39 pm |
|
 |
|
10nisman94
Novice
Joined: Mon Oct 13, 2008 6:29 pm Posts: 75 Location: Florida, USA
|
 Re: different autonomous programs depending on start positition
good point
_________________ PHUHS Robotics Team 516 FTW
Daytona Robofest Winning Alliance Captain Daytona Robofest Inspire Award
|
| Thu Feb 19, 2009 9:57 pm |
|
 |
|
Jeff McBride
Professor
Joined: Fri Sep 19, 2008 1:22 am Posts: 200
|
 Re: different autonomous programs depending on start positition
Our team uses a single program that handles both teleop and autonomous modes and automatically detects the starting position and does the correct thing. We are using a HiTechnic Color sensor to detect the red or blue of the two upper platforms. That tells us if we are off-floor and which color we are. If we see grey we know we are on the floor but not what alliance we are. At the start of autonomous mode we move forward until we see non-grey. At that point we know which alliance we are on. At that point, regardless of our starting position, we know how far we have to move and which directions we need to turn for each step of the autonomous task.
_________________ Jeff McBride Benson Robotics Club
|
| Fri Feb 20, 2009 4:03 am |
|
 |
|
10nisman94
Novice
Joined: Mon Oct 13, 2008 6:29 pm Posts: 75 Location: Florida, USA
|
 Re: different autonomous programs depending on start positition
very cool, could that be done with a regular light sensor?
_________________ PHUHS Robotics Team 516 FTW
Daytona Robofest Winning Alliance Captain Daytona Robofest Inspire Award
|
| Fri Feb 20, 2009 8:08 am |
|
 |
|
chadgeorge
Novice
Joined: Fri Oct 24, 2008 8:58 am Posts: 87
|
 Re: different autonomous programs depending on start positition
yes. cool idea. Another option (depending on starting orientation) is to detect which side of the robot is next to the wall. Thats how we do it. If the wall is to the right we're on the red alliance. If the wall is to the left we're on the blue alliance. I think I'll adopt the color sensor idea too for on field vs off field. I've been wanting to find some way of using that sensor 
|
| Fri Feb 20, 2009 9:52 am |
|
 |
|
Jeff McBride
Professor
Joined: Fri Sep 19, 2008 1:22 am Posts: 200
|
 Re: different autonomous programs depending on start positition
We haven't tried it. I suggest testing it to see if you can differentiate between the specific blue, grey and red colors used on the field as different grey-scale values from the light sensor. If you can detect grey or not grey (red is the same as blue) then you could use it to determine on-field v/s off-field start and use chadgeorge's idea of wall detection to determine the alliance color. If you are starting off-field you would go forward until you saw the wall and then would know. If red is the same value as grey and blue is different or blue is the same as grey and red is different then you could tell where you are by using the black ramp (it looks grey but I went forward and saw black so I must have been on the RED platform, and so on. Use your imagination. There are a lot of ways to skin this cat. We are also using the color sensor to detect the white lines in autonomous mode for navigation. We could have just as easily used a light sensor for that part of the task.
_________________ Jeff McBride Benson Robotics Club
|
| Mon Feb 23, 2009 5:19 pm |
|
 |
|
Roboram1
Rookie
Joined: Sun Sep 28, 2008 6:09 pm Posts: 4
|
 Re: different autonomous programs depending on start positition
I posted the original question regarding the start position and thanks for all the help. I haven't entered a competition as of yet, but will be entering two the next two weeks. Could anyone tell me who actually puts the robot in the starting positions. Is it a team member or is it a referee? Would it be possible to have two touch sensors with hinged plates over them that could be easliy closed and stay that way? One touch sensor could represent the top and the other the color. If the start position is top - red, the cover on the "top" sensor could be closed to represent - True and the same for the color sensor. This way the autonomous program could jump to the correct point of the program depending on the switch positions.
By the way, today, I did check the different colors with the light sensor and there was enough of a difference (10) so it could be used to determine the start color position.
Thanks,
---Bill Jackson
|
| Mon Feb 23, 2009 9:26 pm |
|
|
Who is online |
Users browsing this forum: No registered users and 3 guests |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum
|
|