I needed to add one more thing of how to use it... here is more example code:
Code:
/***********************************************************************************************************************************/
/* FRC_2012_Robot_Properties */
/***********************************************************************************************************************************/
const double c_WheelDiameter=Inches2Meters(6);
const double c_MotorToWheelGearRatio=12.0/36.0;
FRC_2012_Robot_Properties::FRC_2012_Robot_Properties() : m_TurretProps(
"Turret",
2.0, //Mass
0.0, //Dimension (this really does not matter for this, there is currently no functionality for this property, although it could impact limits)
10.0, //Max Speed
1.0,1.0, //ACCEL, BRAKE (These can be ignored)
10.0,10.0, //Max Acceleration Forward/Reverse
Ship_1D_Properties::eSwivel,
true, //Using the range
-Pi,Pi
),
m_PitchRampProps(
"Pitch",
2.0, //Mass
0.0, //Dimension (this really does not matter for this, there is currently no functionality for this property, although it could impact limits)
10.0, //Max Speed
1.0,1.0, //ACCEL, BRAKE (These can be ignored)
10.0,10.0, //Max Acceleration Forward/Reverse
Ship_1D_Properties::eRobotArm,
true, //Using the range
DEG_2_RAD(45-3),DEG_2_RAD(70+3) //add padding for quick response time (as close to limits will slow it down)
),
m_PowerWheelProps(
"PowerWheels",
2.0, //Mass
Inches2Meters(6), //Dimension (needed to convert linear to angular velocity)
(5000.0/60.0) * Pi2, //Max Speed (This is clocked at 5000 rpm)
60.0,60.0, //ACCEL, BRAKE (These work with the buttons, give max acceleration)
60.0,60.0, //Max Acceleration Forward/Reverse these can be real fast about a quarter of a second
Ship_1D_Properties::eSimpleMotor,
false,28.0 * Pi2,0.0, //No limit ever! (but we are using the min range as a way to set minimum speed)
true //This is angular
),
m_ConveyorProps(
"Conveyor",
2.0, //Mass
0.0, //Dimension (this really does not matter for this, there is currently no functionality for this property, although it could impact limits)
//RS-550 motor with 64:1 BaneBots transmission, so this is spec at 19300 rpm free, and 17250 peak efficiency
//17250 / 64 = 287.5 = rps of motor / 64 reduction = 4.492 rps * 2pi = 28.22524
28, //Max Speed (rounded as we need not have precision)
112.0,112.0, //ACCEL, BRAKE (These work with the buttons, give max acceleration)
112.0,112.0, //Max Acceleration Forward/Reverse these can be real fast about a quarter of a second
Ship_1D_Properties::eSimpleMotor,
false,0.0,0.0, //No limit ever!
true //This is angular
),
m_FlipperProps(
"Flippers",
2.0, //Mass
Inches2Meters(12), //Dimension (this should be correct)
1.4 * Pi2, //Max Speed (Parker gave this one, should be good)
10.0,10.0, //ACCEL, BRAKE (should be relatively quick)
10.0,10.0, //Max Acceleration Forward/Reverse
Ship_1D_Properties::eRobotArm,
true, //Using the range
-PI_2,PI_2 //TODO
)
{
{
FRC_2012_Robot_Props props;
const double KeyDistance=Inches2Meters(144);
const double KeyWidth=Inches2Meters(101);
//const double KeyDepth=Inches2Meters(48); //not used (yet)
const double DefaultY=c_HalfCourtLength-KeyDistance;
const double HalfKeyWidth=KeyWidth/2.0;
props.PresetPositions[0]=Vec2D(0.0,DefaultY);
props.PresetPositions[1]=Vec2D(-HalfKeyWidth,DefaultY);
props.PresetPositions[2]=Vec2D(HalfKeyWidth,DefaultY);
props.FireTriggerDelay=0.100; //e.g. 10 iterations of good tolerance
props.FireButtonStayOn_Time=0.100; //100 ms
props.Coordinates_DiplayRow=(size_t)-1;
props.TargetVars_DisplayRow=(size_t)-1;
props.PowerVelocity_DisplayRow=(size_t)-1;
for (size_t row=0;row<3;row++)
{
for (size_t column=0;column<3;column++)
{
Vec2D &cell=props.KeyGrid[row][column];
const double spread=Feet2Meters(7.0);
const double x=spread * ((double)column-1.0);
const double y=(spread * ((double)row-1.0)) + DefaultY;
cell=Vec2D(x,y);
props.KeyCorrections[row][column].PowerCorrection=1.0;
props.KeyCorrections[row][column].YawCorrection=1.0;
}
}
FRC_2012_Robot_Props::Autonomous_Properties &auton=props.Autonomous_Props;
auton.MoveForward=0.0;
auton.TwoShotScaler=1.0;
auton.RampLeft_ErrorCorrection_Offset=
auton.RampRight_ErrorCorrection_Offset=
auton.RampCenter_ErrorCorrection_Offset=Vec2D(0.0,0.0);
auton.XLeftArc=auton.XRightArc=1.9;
FRC_2012_Robot_Props::Autonomous_Properties::WaitForBall_Info &ball_1=auton.FirstBall_Wait;
ball_1.InitialWait=4.0;
ball_1.TimeOutWait=-1.0;
ball_1.ToleranceThreshold=0.0;
FRC_2012_Robot_Props::Autonomous_Properties::WaitForBall_Info &ball_2=auton.SecondBall_Wait;
ball_2.InitialWait=4.0;
ball_2.TimeOutWait=-1.0;
ball_2.ToleranceThreshold=0.0;
m_FRC2012RobotProps=props;
}
{
Tank_Robot_Props props=m_TankRobotProps; //start with super class settings
//Late assign this to override the initial default
//Was originally 0.4953 19.5 width for 2011
//Now is 0.517652 20.38 according to Parker (not too worried about the length)
props.WheelDimensions=Vec2D(0.517652,0.6985); //27.5 x 20.38
props.WheelDiameter=c_WheelDiameter;
props.LeftPID[1]=props.RightPID[1]=1.0; //set the I's to one... so it should be 1,1,0
props.MotorToWheelGearRatio=c_MotorToWheelGearRatio;
m_TankRobotProps=props;
}
{
Rotary_Props props=m_TurretProps.RoteryProps(); //start with super class settings
props.PID[0]=1.0;
props.PrecisionTolerance=0.001; //we need high precision
m_TurretProps.RoteryProps()=props;
}
{
Rotary_Props props=m_PitchRampProps.RoteryProps(); //start with super class settings
props.PID[0]=1.0;
props.PrecisionTolerance=0.001; //we need high precision
m_PitchRampProps.RoteryProps()=props;
}
{
Rotary_Props props=m_PowerWheelProps.RoteryProps(); //start with super class settings
props.PID[0]=1.0;
props.PrecisionTolerance=0.1; //we need decent precision (this will depend on ramp up time too)
m_PowerWheelProps.RoteryProps()=props;
}
}
const char *ProcessVec2D(FRC_2012_Robot_Props &m_FRC2012RobotProps,Scripting::Script& script,Vec2d &Dest)
{
const char *err;
typedef FRC_2012_Robot_Properties::Vec2D Vec2D;
double length, width;
//If someone is going through the trouble of providing the dimension field I should expect them to provide all the fields!
err = script.GetField("y", NULL, NULL,&length);
if (err)
{
err = script.GetField("y_ft", NULL, NULL,&length);
if (!err)
length=Feet2Meters(length);
else
{
err = script.GetField("y_in", NULL, NULL,&length);
if (!err)
length=Inches2Meters(length);
}
}
ASSERT_MSG(!err, err);
err = script.GetField("x", NULL, NULL,&width);
if (err)
{
err = script.GetField("x_ft", NULL, NULL,&width);
if (!err)
width=Feet2Meters(width);
else
{
err = script.GetField("x_in", NULL, NULL,&width);
if (!err)
width=Inches2Meters(width);
}
}
ASSERT_MSG(!err, err);
Dest=Vec2D(width,length); //x,y where x=width
script.Pop();
return err;
}
const char *ProcessKey(FRC_2012_Robot_Props &m_FRC2012RobotProps,Scripting::Script& script,size_t index)
{
const char *err;
typedef FRC_2012_Robot_Properties::Vec2D Vec2D;
Vec2D PresetPosition;
err=ProcessVec2D(m_FRC2012RobotProps,script,PresetPosition);
ASSERT_MSG(!err, err);
PresetPosition[1]=c_HalfCourtLength-PresetPosition[1];
m_FRC2012RobotProps.PresetPositions[index]=PresetPosition; //x,y where x=width
return err;
}
const char *ProcessKeyCorrection(FRC_2012_Robot_Props &m_FRC2012RobotProps,Scripting::Script& script,size_t row,size_t column)
{
const char* err=NULL;
char CellName[4];
CellName[0]='c';
CellName[1]='1'+row;
CellName[2]='1'+column;
CellName[3]=0;
err = script.GetFieldTable(CellName);
err = script.GetField("p", NULL, NULL,&m_FRC2012RobotProps.KeyCorrections[row][column].PowerCorrection);
err = script.GetField("x", NULL, NULL,&m_FRC2012RobotProps.KeyCorrections[row][column].YawCorrection);
script.Pop();
return err;
}
void FRC_2012_Robot_Properties::LoadFromScript(Scripting::Script& script)
{
const char* err=NULL;
__super::LoadFromScript(script);
err = script.GetFieldTable("robot_settings");
if (!err)
{
err = script.GetFieldTable("turret");
if (!err)
{
m_TurretProps.LoadFromScript(script);
script.Pop();
}
err = script.GetFieldTable("pitch");
if (!err)
{
m_PitchRampProps.LoadFromScript(script);
script.Pop();
}
err = script.GetFieldTable("power");
if (!err)
{
m_PowerWheelProps.LoadFromScript(script);
script.Pop();
}
err = script.GetFieldTable("conveyor");
if (!err)
{
m_ConveyorProps.LoadFromScript(script);
script.Pop();
}
err = script.GetFieldTable("flippers");
if (!err)
{
m_FlipperProps.LoadFromScript(script);
script.Pop();
}
m_LowGearProps=*this; //copy redundant data first
err = script.GetFieldTable("low_gear");
if (!err)
{
m_LowGearProps.LoadFromScript(script);
script.Pop();
}
err = script.GetFieldTable("key_1");
if (!err) ProcessKey(m_FRC2012RobotProps,script,0);
err = script.GetFieldTable("key_2");
if (!err) ProcessKey(m_FRC2012RobotProps,script,1);
err = script.GetFieldTable("key_3");
if (!err) ProcessKey(m_FRC2012RobotProps,script,2);
double fDisplayRow;
err=script.GetField("ds_display_row", NULL, NULL, &fDisplayRow);
if (!err)
m_FRC2012RobotProps.Coordinates_DiplayRow=(size_t)fDisplayRow;
err=script.GetField("ds_target_vars_row", NULL, NULL, &fDisplayRow);
if (!err)
m_FRC2012RobotProps.TargetVars_DisplayRow=(size_t)fDisplayRow;
err=script.GetField("ds_power_velocity_row", NULL, NULL, &fDisplayRow);
if (!err)
m_FRC2012RobotProps.PowerVelocity_DisplayRow=(size_t)fDisplayRow;
script.GetField("fire_trigger_delay", NULL, NULL, &m_FRC2012RobotProps.FireTriggerDelay);
script.GetField("fire_stay_on_time", NULL, NULL, &m_FRC2012RobotProps.FireButtonStayOn_Time);
err = script.GetFieldTable("grid_corrections");
if (!err)
{
for (size_t row=0;row<3;row++)
{
for (size_t column=0;column<3;column++)
{
err=ProcessKeyCorrection(m_FRC2012RobotProps,script,row,column);
assert(!err);
}
}
script.Pop();
}
err = script.GetFieldTable("auton");
if (!err)
{
struct FRC_2012_Robot_Props::Autonomous_Properties &auton=m_FRC2012RobotProps.Autonomous_Props;
{
double length;
err = script.GetField("move_forward_ft", NULL, NULL,&length);
if (!err)
auton.MoveForward=Feet2Meters(length);
}
err = script.GetField("two_shot_scaler", NULL, NULL,&auton.TwoShotScaler);
err = script.GetFieldTable("ramp_left");
if (!err)
{
Vec2D OffsetPosition;
err=ProcessVec2D(m_FRC2012RobotProps,script,OffsetPosition);
ASSERT_MSG(!err, err);
auton.RampLeft_ErrorCorrection_Offset=OffsetPosition;
}
err = script.GetFieldTable("ramp_right");
if (!err)
{
Vec2D OffsetPosition;
err=ProcessVec2D(m_FRC2012RobotProps,script,OffsetPosition);
ASSERT_MSG(!err, err);
auton.RampRight_ErrorCorrection_Offset=OffsetPosition;
}
err = script.GetFieldTable("ramp_center");
if (!err)
{
Vec2D OffsetPosition;
err=ProcessVec2D(m_FRC2012RobotProps,script,OffsetPosition);
ASSERT_MSG(!err, err);
auton.RampCenter_ErrorCorrection_Offset=OffsetPosition;
}
{
const char * const fieldTable[]=
{
"ball_1","ball_2"
};
//You just gotta love pointers to do this! ;)
FRC_2012_Robot_Props::Autonomous_Properties::WaitForBall_Info *ballTable[]=
{
&auton.FirstBall_Wait,&auton.SecondBall_Wait
};
for (size_t i=0;i<2;i++)
{
err = script.GetFieldTable(fieldTable[i]);
if (!err)
{
FRC_2012_Robot_Props::Autonomous_Properties::WaitForBall_Info &ball=*ballTable[i];
err=script.GetField("initial_wait", NULL, NULL, &ball.InitialWait);
ASSERT_MSG(!err, err);
err=script.GetField("timeout_wait", NULL, NULL, &ball.TimeOutWait);
ASSERT_MSG(!err, err);
err=script.GetField("tolerance", NULL, NULL, &ball.ToleranceThreshold);
ASSERT_MSG(!err, err);
script.Pop();
}
}
}
script.GetField("x_left_arc", NULL, NULL, &auton.XLeftArc);
script.GetField("x_right_arc", NULL, NULL, &auton.XRightArc);
script.Pop();
}
err = script.GetFieldTable("controls");
if (!err)
{
const char * const Events[] =
{
"Joystick_SetCurrentSpeed_2","Analog_Turn",
"Turret_SetCurrentVelocity","Turret_SetIntendedPosition","Turret_SetPotentiometerSafety",
"PitchRamp_SetCurrentVelocity","PitchRamp_SetIntendedPosition","PitchRamp_SetPotentiometerSafety",
"PowerWheels_SetCurrentVelocity","PowerWheels_SetEncoderSafety","PowerWheels_IsRunning",
"Ball_SetCurrentVelocity","Ball_Fire","Ball_Squirt","Ball_Grip","Ball_GripL","Ball_GripM","Ball_GripH",
"Flippers_SetCurrentVelocity","Flippers_SetIntendedPosition","Flippers_SetPotentiometerSafety",
"Flippers_Advance","Flippers_Retract",
"Robot_IsTargeting","Robot_SetTargetingOn","Robot_SetTargetingOff","Robot_TurretSetTargetingOff","Robot_SetTargetingValue",
"Robot_SetLowGear","Robot_SetLowGearOn","Robot_SetLowGearOff","Robot_SetLowGearValue",
"Robot_SetPreset1","Robot_SetPreset2","Robot_SetPreset3","Robot_SetPresetPOV",
"Robot_SetDefensiveKeyValue","Robot_SetDefensiveKeyOn","Robot_SetDefensiveKeyOff",
"Robot_SetCreepMode","Robot_Flippers_Solenoid"
//AI Tester events only
#if 1
,"Ball_SlowWheel"
#endif
};
//TODO we may use actual product names here, but this will be fine for wind river build
const char * const Controls[] =
{
"Joystick_1","Joystick_2","Joystick_3"
};
for (size_t i=0;i<_countof(Controls);i++)
{
err = script.GetFieldTable(Controls[i]);
if (!err)
{
Control_Props control;
//Wind River uses generic name, and AI tester uses product name
//control.Controller=Controls[i];
err=script.GetField("control", &control.Controller, NULL, NULL);
for (size_t j=0;j<_countof(Events);j++)
{
UI_Controller::Controller_Element_Properties element;
err=UI_Controller::ExtractControllerElementProperties(element,Events[j],script);
if (!err)
control.EventList.push_back(element);
}
m_RobotControls.push_back(control);
script.Pop();
}
}
}
script.Pop();
}
}