Go Down

### Topic: Issue using abs() (Read 2069 times)previous topic - next topic

#### DryRun

##### Jul 14, 2019, 06:06 pmLast Edit: Jul 14, 2019, 06:07 pm by DryRun
Hi,

I want to replace this function and use abs() to find the absolute value.

Code: [Select]
`if (speed < 0)                                    speed = -speed;`
with
Code: [Select]
`speed = abs(speed);`

But it's not equivalent for some reason?? Am i using abs() correctly?

#### UKHeliBob

#1
##### Jul 14, 2019, 06:11 pm
How is speed declared ?
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

#### Delta_G

#2
##### Jul 14, 2019, 06:13 pm
But it's not equivalent for some reason??
What result do you get?  That should be perfectly fine.  The only caveat with abs is to remember that it is a macro and not a function so watch out if you have to write an expression in there twice.  But in the trivial example you show in your post it should be the same.

Post a complete test code and output that demonstrates your issue.
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

#### DryRun

#3
##### Jul 14, 2019, 06:14 pm
How is speed declared ?
Code: [Select]
`float speed;`

From the example given on: https://www.arduino.cc/reference/en/language/functions/math/abs/
I'm wondering if the correct use of abs() should just be:
Code: [Select]
`abs(speed);`
Code: [Select]
`speed = abs(speed);`
?

#### jremington

#4
##### Jul 14, 2019, 06:15 pmLast Edit: Jul 14, 2019, 06:15 pm by jremington
fabs() for floats/doubles

#### Delta_G

#5
##### Jul 14, 2019, 06:18 pm
fabs() for floats/doubles
And that's why it is important to post a complete piece of code and not just the one dumb line you can't tell anything is wrong from.
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

#### oqibidipo

#6
##### Jul 14, 2019, 06:34 pm
fabs() for floats/doubles
And to make things more confusing, Arduino.h defines abs() as
Code: [Select]
`#define abs(x) ((x)>0?(x):-(x))`

#### DryRun

#7
##### Jul 14, 2019, 09:37 pmLast Edit: Jul 14, 2019, 10:30 pm by DryRun
But there is no mention of fabs() in the Arduino reference docs.
https://www.arduino.cc/reference/en/language/functions/math/fabs/ gives an error. Maybe this should be added. Unless it's not officially supported?

And that's why it is important to post a complete piece of code and not just the one dumb line you can't tell anything is wrong from.
My apologies... but i had only started writing the function at that time. I am trying to calculate the speed of rotation of my robot using the encoders on both wheels. I am sending the commands via serial monitor to turn the robot right or left. Here is what i have so far:

Code: [Select]
`int left, right, turnout = 0;   //global variables//the turn function. It uses the encoder pulse values from both DC motors to calculate current //speed of rotation and then based on the user command, turns left or right, and outputs the //appropriate PWM value to send to each motor.void turn()      {     float turnspeed = 0;  float rotationratio = 0;  int turnmin = -5, turnmax = 5;     if (left == 1 || right == 1)  {                                    turnspeed = (pulseright + pulseleft);  //current turn speed; variables of type int; pulseright and pulseleft have polarities.        turnspeed = abs(turnspeed);     //should return absolute float value of turn speed        rotationratio = 5 / turnspeed;          //set the speed of rotation        if (rotationratio <= 5)    {      rotationratio = 0.5;    }         if (rotationratio > 5)  //this implies that turnspeed < 1    {      rotationratio = 5;    }  }  if (left ==1)   {    turnout += rotationratio;  }  else if (right == 1 )  {    turnout -= rotationratio;  }  else turnout = 0;    if (turnout > turnmax)       turnout = turnmax;     //the max value setting of amplitude  if (turnout < turnmin)       turnout = turnmin;      //the min value setting of amplitude     Turn_pwm = turnout;    //PWM value sent to both motors to initiate the rotation of the robot}`

When i tried
Code: [Select]
`turnspeed = fabs(turnspeed);` it doesn't work, for some reason.

#### septillion

#8
##### Jul 14, 2019, 09:51 pm
fabs() and abs() don't alter the variable, so you must assign it to something which can be the same variable again if you only want to store an absolute version. So
Code: [Select]
`var = abs(var);//orabsf(var);`

And yeah, some functions that come from standard C libraries are not explicitly documented on Arduino. In this case because (although I hate the implementation), abs() should work just fine.
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake

#### DryRun

#9
##### Jul 14, 2019, 09:57 pmLast Edit: Jul 14, 2019, 10:09 pm by DryRun
So, this is the code that i had previously in the function  for absolute value of speed and it worked:
Code: [Select]
`if (turnspeed < 0)     //absolute value of current speed   {     turnspeed = -turnspeed;`
But after i replaced it with the following, it's not working anymore, as there is no PWM output to the motors.
Code: [Select]
`turnspeed = abs(turnspeed);`

#### UKHeliBob

#10
##### Jul 14, 2019, 10:20 pm
What do you see if you print turnspeed ?
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

#### DryRun

#11
##### Jul 14, 2019, 10:28 pmLast Edit: Jul 14, 2019, 10:29 pm by DryRun
What do you see if you print turnspeed ?
Output from Serial Monitor:
Code: [Select]
`29.0013.000.0024.0010.0034.0018.005.0029.0014.000.0024.0010.0034.0020.006.0029.0014.000.0024.0010.0033.0018.004.0028.0014.000.0024.009.0033.0019.004.0028.0014.000.0024.0010.0034.0020.005.0029.0015.000.0024.0010.0033.0019.005.0029.0014.000.0024.009.0032.0019.004.0028.0014.000.0024.0010.0034.00`

So, it's working as expected to output only positive values of the encoder rotation speed. But for some reason, there is no PWM output, meaning that the variable 'turnout' is zero.

#### Delta_G

#12
##### Jul 14, 2019, 10:28 pmLast Edit: Jul 14, 2019, 10:32 pm by Delta_G
Code: [Select]
`turnspeed = (pulseright + pulseleft);`

What are pulseright and pulseleft?

Please, can we have a complete example that we can compile and test that exhibits the problem instead of snippets?

https://snippets-r-us.com/
https://stackoverflow.com/help/minimal-reproducible-example

where do left and right get values?
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

#### Delta_G

#13
##### Jul 14, 2019, 10:30 pm
Code: [Select]
`fabs(turnspeed);     //should return absolute float value of turn speed`

It does return the absolute value, but this line is as useless as writing:

Code: [Select]
`27.5;`

It doesn't store the value anywhere.  It doesn't alter the value of turnspeed.

You need:

Code: [Select]
`turnspeed = fabs(turnspeed);`
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

#### pert

#14
##### Jul 14, 2019, 11:09 pm
But there is no mention of fabs() in the Arduino reference docs.
https://www.arduino.cc/reference/en/language/functions/math/fabs/ gives an error. Maybe this should be added.
We do have adding documentation for this and the many other undocumented math functions on the "to-do" list:
https://github.com/arduino/reference-en/issues/522
and some related discussion here:
https://github.com/arduino/reference-en/issues/362

There is a weird situation because some cores use the Arduino macro implementation of abs(), which works with any type, while other cores (including Arduino megaAVR Boards, ESP8266, and ESP32) use the standard implementation of abs(), which does not work with float. So it's pretty much a huge mess and the incomplete documentation doesn't help matters.

Unless it's not officially supported?
I don't really know what "officially supported" means.

Go Up