Shop OBEX P1 Docs P2 Docs Learn Events
Trigonometry and calculations with an output as a variable — Parallax Forums

Trigonometry and calculations with an output as a variable

SkiddyJellyfishSkiddyJellyfish Posts: 1
edited 2013-03-06 14:53 in Propeller 1
For a project, I need my propeller chip to calculate trigonemetic values and other opertaions to recieve an output that can be used in another equation. This output will be used to control a servo motor with pulses between 1000 and 2000. For the servos, I am using the object Servo32v7. I have tried to use Float32Full and the Spin_Trigpack, but both have proved unsuccesful. Although, I want to use the output of the equation as a variable, it comes out either as string or 32 bit floating point value. Is there any way that I can create code that will properly execute my equation and and return it as a normal variable? My previous attempts at truncation and conversion only return 1s or 0s, making sine only work at 0, 90, 180, and 270 degrees.

Also, my equtaion:

O = tan^-1(((AsinAlpha)-M)/((sqroot((A^2)-(Y^2)))

I gather M, Alpha, and A from sensors, but the rest of the variables are solved by the equation in one way or another. (the variables refer to a diagram)

Any help or advice is greatly, greatly appreciated.

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-03-06 12:15
    I found learning to use a floating point object with the Propeller a bit of a challenge.

    What's important to remember is you can't mix integers and floats. All operations done with a floating point variable needs to be done using a floating point object including displaying the number.

    I have an example program that uses a magnetometer to compute compass headings here.

    I'm afraid it's not a super simple example. If you can't make sense of the program let us know and one of us will probably be able to find a more simplified example.
    Is there any way that I can create code that will properly execute my equation and and return it as a normal variable? My previous attempts at truncation and conversion only return 1s or 0s, making sine only work at 0, 90, 180, and 270 degrees.

    Here's the problem the next integer up from zero is one. If you want your variable to contain an integer but also want the integer to represent a fractional value, then you'll want to use pseudo real numbers. In the link above, I show how to return the integer value of a trig function as 1000 times the real answer. So if the answer to the equation were 0.5, instead of returning zero the above program returns the value 500 (1000 * 0.5). The program also includes a method for displaying this pseudo real number.

    The program is bit cryptic since it uses variable addresses instead of the variable names. I was developing the program to use as a child object and wanted the parent object to contain the variables to be filled.

    Again, if you have trouble making sense of it, make sure and let us know.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-03-06 14:53
    I trimmed away all the magnetometer specific parts of the program I linked to earlier. I also switched from using the addresses of variables to using the variable names.

    I also hard coded the values of the sensor readings.

    The attached program will have static values, but if you change it so the x, y and z variables are the input from your sensors (and you change the equation to match your the one you want to use), it should work.

    It compiles and displays this:
    X = 30 , Y = 50, Z =40
    
    Course = 59.036  tiltX = 53.130, tiltY = -38.660
    

    The method "GetRaw" is the part that does the calculation. It converts x, y and z into floating point number, uses the floats in a calculation, and before using the "Round" method, it multiplies the number by floating point number 1000.0. This multiplication allows the integer number to retain more precision. You just have to keep in mind that the number is a thousand times larger than it really is.

    Here's the GetRaw method:
    PUB GetRaw | fX, fY, fZ   ' Get raw data from continous output
    
    
      x := 30 ' x, y & z could be read from sensor
      z := 40 
      y := 50 
    
    
      fX := F.FFloat(x)
      fY := F.FFloat(y)
      fZ := F.FFloat(z)
     
      pseudoHeading := F.FRound(F.FMul(F.Degrees(F.ATan2(fY, fX)), 1000.0))
      pseudoTiltX := F.FRound(F.FMul(F.Degrees(F.ATan2(fZ, fX)), 1000.0))
      pseudoTiltY := F.FRound(F.FMul(F.Degrees(F.ATan2(fZ, fY)), 1000.0))
      
    
    
    

    Hopefully this code will be easier to understand.
Sign In or Register to comment.