|
#1
|
||||
|
||||
|
RobotC programming tips
We've had thread like this before, however, though I would start a new one for RobotC programmers to post their tips and tricks.
To start it off here are a couple that may not be known. functions can have default values for their parameters, for example. Code:
/ pointless demo code
void
forward( int speed = 100 )
{
motor[ port2 ] = speed;
}
task main()
{
// Forward at default
forward( );
// Forward at speed 10
forward( 10 );
// Do nothing
while( true ){
wait10Msec(500);
}
}
If you have included your own library of functions, for example. Code:
#include "motorLib.c" Code:
#pragma systemFile // eliminates warning for "unreferenced" functions |
|
#2
|
||||
|
||||
|
Re: RobotC programming tips
I guess I'll start off with something simple: ternary operators. Obviously this isn't specifically for ROBOTC, but many beginners don't know about it. I find it to be very useful in shortening code. A ternary operation will look something like this:
Code:
value = (boolean statement) ? (value if statement is true) : (value if statement is false); Code:
motor[port2] = abs(vexRT[Ch2]) > 10 ? vexRT[Ch2] : 0; Code:
if(abs(vexRT[Ch2]) > 10)){
motor[port2] = vexRT[Ch2];
}else{
motor[port2] = 0;
}
Code:
motor[port2] = vexRT[Ch2] > 10 ? vexRT[Ch2] : vexRT[Ch2 < -10 ? (vexRT[Ch2] / 2) : 0; |
|
#4
|
||||
|
||||
|
Re: RobotC programming tips
Structs are useful when doing more complex programming. For those who don't know what they are, structs are variables made of a collection of other variables. Again, this is not unique to ROBOTC, but still useful in general, and not as widely known to beginning programmers. I'll demonstrate with an example:
Code:
typedef struct{
int maxPos;
int minPos;
int armSpeed;
int prevSensorValues[10];
} robotArm;
A struct is implemented, and its components are accessed like this: Code:
robotArm leftArm; leftArm.maxPos = 2000; leftArm.minPos = 150; leftArm.armSpeed = 100; |
|
#5
|
||||
|
||||
|
Re: RobotC programming tips
how do i import a library of functions? Cause that would be epic. Right now my program is cluttered with all the functions i have written, which i can share with you guys. It might not be written in the best way possible, but they are quite nifty. I don't have the actual code with me so i can't copy past but the one i like a lot is basically this:
Code:
void drivedistance(int distance)
{
rotations = distance / "wheel circumference";
rotations = rotations * "number of rotations of optical shaft for one rotation of wheel";
while(SensorValue(shaft) < rotations)
{
GO FORWARD
}
stop
}
|
|
#6
|
||||
|
||||
|
Re: RobotC programming tips
Quote:
If you are asking how to use a library with RobotC, well, RobotC doesn't really use libraries in the traditional sense but you can include another source file at the beginning of you code using the #include directive. Code:
#include "myfile.c" Last edited by jpearman; 10-02-2011 at 09:17 PM. Reason: typo |
|
#8
|
||||
|
||||
|
Re: RobotC programming tips
Here's another tip demonstrating the use of the switch statement.
Let's say you have a motor that you want to drive forward if you press one button and backwards if you press a different button. If you press both or neither buttons the motor should be stopped. You could program this with cascaded if..then..else statements but another way is to combine the two buttons into one variable and use a switch statement. The "<<" is a shift left operator which is often used instead of multiply by 2. DriveLiftMotor would be a function to actually send values to the motor. Everything in capitals are constants defined elsewhere in the code. Code:
// LiftCtl will be 0, 1, 2 or 3 depending on which buttons are pressed
LiftCtl = (vexRT[ LIFT_DN_BUTTON ] << 1) + vexRT[ LIFT_UP_BUTTON ];
switch( LiftCtl )
{
case 1: // first button pressed
DriveLiftMotor( LIFT_UP_SPEED );
break;
case 2: // second button pressed
DriveLiftMotor( LIFT_DN_SPEED );
break;
default: // either neither or both buttons pressed
DriveLiftMotor( 0 );
break;
}
|
|
#9
|
||||
|
||||
|
Re: RobotC programming tips
There have been several questions recently about moving part of the robot until it has reached a certain position. I though I would post a RobotC example showing how to drive a motor forwards or backwards while monitoring an encoder. This same idea could be used for raising a lift or anything else where an encoder is used to monitor the rotation of a motor.
Anytime a loop is used waiting for a terminal condition to be found it's important to think about what will happen if something goes wrong. This code also shows how to use a timeout so that if an error occurs, the motor stalls for example, the test will stop after a period of time. This code is a simple example and does not use multi tasking or the built in timer both of which could be used as part of this. Code:
#pragma config(Sensor, dgtl1, encoder, sensorQuadEncoder) #pragma config(Motor, port2, MyMotor, tmotorNormal, openLoop) //*!!Code automatically generated by 'ROBOTC' configuration wizard !!*// /*-----------------------------------------------------------------------------*/ /* */ /* Drive motor until an encoder has counted for a number of counts */ /* or a timeout period has passed. */ /* */ /* Assumes the encoder will count up when the motors are running forwards */ /* */ /*-----------------------------------------------------------------------------*/ #define TIMEOUT_CNT_PER_SEC 10 #define MOTOR_FWD_SPEED 64 #define MOTOR_REV_SPEED (-64) #define MOTOR_STOP_SPEED 0 int DriveByEncoder( int encoder_count, int timeout_in_seconds = 5 ) { int timeout; // Drive motor until encoder has moved a number counts or // timeout_in_seconds seconds have passed // Zero the encoder SensorValue[ encoder ] = 0; // Run the motor forwards or backwards if( encoder_count > 0 ) motor[ MyMotor ] = MOTOR_FWD_SPEED; else motor[ MyMotor ] = MOTOR_REV_SPEED; // run loop until encoder hits encoder_count counts or timeout reached for( timeout=(timeout_in_seconds*TIMEOUT_CNT_PER_SEC); timeout > 0; timeout-- ) { // check encoder if( encoder_count > 0 ) { // going forwards if( SensorValue[ encoder ] >= encoder_count ) break; } else { // going backwards if( SensorValue[ encoder ] <= encoder_count ) break; } // wait 1/10 second wait1Msec( 100 ); } // Stop the motor motor[ MyMotor ] = MOTOR_STOP_SPEED; // See if we sucessfully found the right encoder value if( timeout <= 0 ) { // there was an error - perhaps do something // return error return (-1); } else // return success return 0; } /*-----------------------------------------------------------------------------*/ /* */ /* Test the new function */ /* */ /*-----------------------------------------------------------------------------*/ task main() { // forwards until 200 counts DriveByEncoder( 200 ); // short wait wait10Msec( 200 ); // backwards for 3000 counts with a 10 second timeout DriveByEncoder( -3000, 10 ); // demo done while(true) wait1Msec( 10 ); } |
|
#10
|
||||
|
||||
|
Re: RobotC programming tips
Quote:
Society of robots is a great site to visit for anything robotics related in general. Anyway, here is an example: Code:
const double ERR_MTRPWR_RATIO = .05;
const int MTR_THRESH = 20
const int MAX_ARM = 3000;
const int MIN_ARM = 500;
int armPosition = 0;
int motorPower = 0;
task keepArmInPosition(){
while(true){
motorPower = (armPosition - SensorValue[armPot]) * ERR_MTRPWR_RATIO;
motor[arm] = abs(motorPower) > MTR_THRESH ? motorPower : 0;
endTimeSlice();
}
}
task main(){
StartTask(keepArmInPosition);
while(true){
//code
armPos = 300;
endTimeSlice();
}
}
Here is a rundown of the constants: ERR_MTRPWR_RATIO: How much the motor responds to one unit of error. How much the motor power will change for every potentiometer tick away from your expected arm position. MTR_THRESH: Threshold below which the motor will not run. This is to prevent burned out motors and jerkiness. Since you will never exactly stay at the potentiometer value that you want (the ticks are very very small) this is to stop the motor from spasming when the error is very small. MAX_ARM: The maximum potentiometr value that you want your arm to go to. MIN_ARM: The minimum potentiometer value that you want your arm to go to. |
![]() |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
|
|