Unofficial Response To: Absolute value and code help

@Sgarg14 The reason your encoders go on forever is that the encoder is * backward * meaning even if your bot goes forward, the encoder is turning in the negative direction. Since you said while less than positive 5 revolutions (which is 1800 ticks), keep running the motors. In theory, the encoder should reach that value, but like I said before you are going negative. That means you’ll never reach over 1800 ticks. Now you bring up absolute value and yes it solves this problem. If you absolute value the encoder’s value then you still get a negative value from the sensor, but it’s absolute so you’ll get an increasing positive number that will eventually reach five revolutions.

And I can see you are new, which is fine. Next time post on a channel that allows everyone to respond. Here is the code with absolute value functions:

task main()
{

wait1Msec(2000); // 2 Second Delay

//Clear Encoders
SensorValue[motorencoder] = 0;

//to actually absolute value something, type fabs() and put the value you want to absolute value
while(fabs(SensorValue[motorencoder]) < 1500) // While less than 5 rotations on the leftEncoder...
{
//...Move Forward
motor[rightmotor] = 127;
}
wait1Msec(2000);

SensorValue[motorencoder] = 0;

//to actually absolute value something, type fabs() and put the value you want to absolute value
while(fabs(SensorValue[motorencoder]) < 1500) // While less than 5 rotations on the leftEncoder...
{
//...Move Forward
motor[rightmotor] = -127;
}
SensorValue[motorencoder] = 0;
}

Is there a difference between the fabs() function and abs()?

I don’t know. I think abs() is some default thing in the C language (really bad theory but I really don’t know). Just use fabs() because if you look at the left you see a functions and commands list and look under Math, it says fabs() is for absolute valuing.

In C


abs()

is used for


long

(numeric) types while


fabs()

(not documented but is available) is used with


float

types. According to the RobotC help you are fine using


abs()

with int, long, short, and float.

Wikipedia - C data types

Edit: typos

ok thanks for replying

i had another question how would you use void statements with encoder values and everything i asked the seniors but they didnt know either so please help me and again thanks for replying

void statements? Do you mean void functions, as in “functions not returning any value”?


void driveDIstance(int distance, int speed) {
    SensorValue[motorencoder] = 0;
    motor[rightmotor] = speed;
    while(abs(SensorValue[motorencoder]) < distance) {
        //...wait...and wait...
        wait1Msec(15);
    }
    motor[rightmotor] = 0;
}

// usage:
driveDistance(1500, 127);
wait1Msec(2000);
driveDistance(1500, -127);

Hm, I would put the statement that sets motor equal to the parameter of speed in the while loop, but that’s just preference.

Please see my explanation why I don’t like this pattern here.

Using a while loop like that seems like just a bulkier version a waitUntil() statement.

Take a look at the definition for waitUntil by right clicking and selecting “go to definition”:


#define waitUntil(condition) while(!(condition)) sleep(5)

It’s literally just an abstracted while loop :slight_smile:

(So I guess its bulkiness is dependant on where you look at it from; verbosity is not always a bad thing)

Absolutely!
But that wasn’t the core of the argument. The setting of the motor power inside the loop was, since inexperienced students, when seeing the pattern of


while (condition) {
    setMotor(motor, speed);
}

tend to read it as “while the condition applies, let the motor run at speed speed” and somehow expecting that the motor will stop on its own once you leave the loop (without an explicit setMotor(motor,0)).
I have seen too many cases of this on the forum to argue against that pattern in simple cases.

While I do agree with you, I would also argue that this is limiting in some ways to the future development of inexperienced programmers. What about when you want to change the speed dynamically inside a loop? Or when you want to stack multiple conditions within a loop?

For me, it seems only practical that teaching students about how you have to explicitly control your motors will put them in good stead for more intermediate or advanced programming topics. Theres an extent in my mind where just telling young programmers to just learn the basics means that they are not limited in their programming achievement by misunderstanding the basis for more advanced topics.

Just my 42 cents.

All covered in the linked topic.
In the end, we’re in violent agreement :slight_smile:

It doesn’t matter where you put the statement, it matters if you remember to put motor]=0; after the loop.

I wouldn’t say that… While it does matter that we stop the motor once we are done with it. It can also come in very helpful to dynamically change motor speed when approaching a target.

E.g. I want to implement a simple P loop to approach my target in autonomous. It’s much easier to do that with the values in the loop (do while() is used for simplicities sake) then before the loop.

float target = 1000; // Target value 
long sensorInput; // Error and PV
const float Kp = 2; // Constant coefficient.

// Do {} While() in order to force it to gather sensor data
// before evaluating the while condition
do {
	sensorInput = SensorValue[mySensor]; // Gather sensor data
	error = target - sensorInput; // Generate an error
	
	motor[myMotor] = error * Kp; // Generate our proportional value
	
	wait1Msec(20); // We can only update MC motors every ~20ms anyway.
}
while(error > 100); // Error condition
motor[myMotor] = 0; // Stop the motor.

why do you have wait1Msec(15) and then wait1Msec(2000) in the actual usage part would it wait for 15 or 2000

The wait(15) is inside the control loop. Since the robot, even at full speed won’t move far in that time, there’s no need to read the sensor more often than that. And 15ms is about the motor update rate, so that’s what you use in more advanced algorithms (like the one shown by @EvolvingJon).

The 2s delay is between the two motions - two sample usages of the functions. The idea was that the robot would go forward 1500 units, then idle for 2s, then go back for 1500 units… but the code is broken (unless you’re using old-style, single-cable quad encoders that counted always up regardless of the direction).

PM me if u need anymore help. i would be glad to look over your code

what do you mean by when you say the code is broken and if it is how do you fix it

what do you mean by when you say the code is broken and if it is how do you fix it