Author Topic: Calculation in Arduino not working out  (Read 6970 times)

0 Members and 1 Guest are viewing this topic.

Offline CatalinaWOW

  • Super Contributor
  • ***
  • Posts: 5239
  • Country: us
Re: Calculation in Arduino not working out
« Reply #25 on: May 14, 2016, 04:02:59 am »
Since you are likely to have predetermined acceleration values and probably limits on maximum velocity this may be an opportunity to completely rethink the approach, using a standard acceleration and decelleration profile.  Then you can pre-calculate the distance spent accelerating and decellerating, and all you ask the Arduino to do is calculate the time to go at constant speed to achieve the total motion desired.  No unstable math required.
 

Offline IanB

  • Super Contributor
  • ***
  • Posts: 11900
  • Country: us
Re: Calculation in Arduino not working out
« Reply #26 on: May 14, 2016, 04:12:00 am »
You should use mathematics to solve this problem.

(Hint: examine the structure of the expression, simplify it, and use a Taylor series expansion.)

With the numbers you have given, the velocity is going to be given with high precision using the following formula:

Code: [Select]
velocity = d / t; // who'd a thunk it?
You should not have any problem doing this in single precision float arithmetic.
« Last Edit: May 14, 2016, 04:13:44 am by IanB »
 
The following users thanked this post: CM800

Offline IanB

  • Super Contributor
  • ***
  • Posts: 11900
  • Country: us
Re: Calculation in Arduino not working out
« Reply #27 on: May 14, 2016, 05:11:33 am »
Details:

 
The following users thanked this post: CM800, helius

Offline helius

  • Super Contributor
  • ***
  • Posts: 3643
  • Country: us
Re: Calculation in Arduino not working out
« Reply #28 on: May 14, 2016, 06:15:37 am »
Very nice worked example. A couple of other answers are still bothering me:
Would it hurt to go belt and braces and try
float tr = (float)  micros();
This literally does nothing. Conversion of arithmetic types is always automatic in assignments.

Quote
Similarly, I believe sqrt() expects doubles and returns a double, use sqrtf to return a float.
This is true (about the return type). But it isn't required that double be of any greater precision than float: on small MCUs this could be a compiler option. The compiler can also infer from the destination of the expression (initializer to float velocity) that greater precision isn't needed, in some cases (not this one).

Whenever I see code that uses floating point and I don't see NAN--well there is always a problem. Pretty much any code that needs to work in a non-hobby environment needs to check validity of inputs and outputs using NAN (look it up).
Silent exceptions are only one possible way to manage exceptional conditions in arithmetic. It is usually better to set the mode register to trap them, and use a SIGFPE handler or equivalent.

Quote
Time is often an issue and sure enough you have: "float t1=micros(); float td=micros()-t1;" So, here, td can be either zero or negative (on some platforms, maybe not yours). So any division by td is now suspect (NAN!).
You cannot expect to divide by a time variable in any program when the length of time may be zero units. This is a logic error (which should be found at the flowchart stage), not a coding issue. If your calculation was with integer types then you do not get notice of overflow (NaNs or otherwise): the program is just undefined.

Quote
Just took another look at micros() definition; it's EVIL!. " This number will overflow (go back to zero), after approximately 70 minutes." So, yeah, that's a totally unreliable number--what if you catch it at a transition. OMG. Useless.
Time counters are defined and intended to be used with unsigned arithmetic, where no such problems occur. If the program is unsigned long tr = micros(); unsigned long td = micros()-tr;, then td will always be the period of time between the two statements, and cannot underflow.
 
The following users thanked this post: CM800

Offline CM800Topic starter

  • Frequent Contributor
  • **
  • Posts: 882
  • Country: 00
Re: Calculation in Arduino not working out
« Reply #29 on: May 14, 2016, 09:08:52 am »
Details:



Hi IanB,

That's some really useful information there. I will have to look into these maths tools further, Time to brush up on my algebra!
I think it's time to call up my maths tutor and get some lessons going again. This could be really useful with some of the directions  I am looking to go.

Not sure why the timer keeps getting brought up by so many people. It is not part of the codes functionality, I was just using it for evaluating the performance roughly as I wasn't sure just how long that equation could take to calculate for the Arduino (next to nothing thankfully)
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Calculation in Arduino not working out
« Reply #30 on: May 14, 2016, 10:42:57 am »
Quote
td = micros()-tr;

That approach is not overflow safe.
================================
https://dannyelectronics.wordpress.com/
 

Offline IanB

  • Super Contributor
  • ***
  • Posts: 11900
  • Country: us
Re: Calculation in Arduino not working out
« Reply #31 on: May 14, 2016, 04:04:28 pm »
Quote
td = micros()-tr;

That approach is not overflow safe.

Refer to what helius said two posts above. With unsigned arithmetic it is safe and it gives the right answer.
« Last Edit: May 14, 2016, 04:06:01 pm by IanB »
 

Offline helius

  • Super Contributor
  • ***
  • Posts: 3643
  • Country: us
Re: Calculation in Arduino not working out
« Reply #32 on: May 14, 2016, 04:06:45 pm »
Quote
td = micros()-tr;
That approach is not overflow safe.
Not the case. See ISO C 6.3.1.8: If one operand is unsigned, and its size is greater than or equal to the other operand, both operands are converted to unsigned and the result is unsigned. Unsigned arithmetic is never subject to overflow, by definition.
 

Offline mav_iqdirect

  • Contributor
  • Posts: 15
  • Country: us
Re: Calculation in Arduino not working out
« Reply #33 on: May 14, 2016, 06:05:53 pm »
You also may try to use double data type instead of float.
 

Offline bingo600

  • Super Contributor
  • ***
  • Posts: 1989
  • Country: dk
Re: Calculation in Arduino not working out
« Reply #34 on: May 14, 2016, 06:16:27 pm »
Since when did avr-gcc/avr-libc get working double precision libs ?

Last i checkked they would treat double like float

/Bingo
 

Offline Rick Law

  • Super Contributor
  • ***
  • Posts: 3442
  • Country: us
Re: Calculation in Arduino not working out
« Reply #35 on: May 14, 2016, 09:41:21 pm »
Since when did avr-gcc/avr-libc get working double precision libs ?

Last i checkked they would treat double like float

/Bingo

They still do.  Arduino library still treats double the same as float and there is NO precision difference.  Double and Float are identical 4 byte variables.

It is like keeping a super model's photo in your wallet.  That isn't going to get you a date with her but you can enjoy the sight.

https://www.arduino.cc/en/Reference/Double
 

Offline richardman

  • Frequent Contributor
  • **
  • Posts: 427
  • Country: us
Re: Calculation in Arduino not working out
« Reply #36 on: May 17, 2016, 08:29:16 am »
To summarize the issue with the "precision" issue, with 32-bit floats, you have ~7.3 decimal digits of precision. Why .3? Because human uses decimal notation and computers use binary. What this means is that you can store

0.1234567eX

where X is the power of ten from -38 to 38 accurately. To do arithmetic though, thinking of it that depending on the operations, you have to normalize the power-of-ten to the same or at least close-by to each other. When you do that, you can then see that if the exponents vary too greatly, then the result will not be accurate.
// richard http://imagecraft.com/
JumpStart C++ for Cortex (compiler/IDE/debugger): the fastest easiest way to get productive on Cortex-M.
Smart.IO: phone App for embedded systems with no app or wireless coding
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf