1. For downloading SimTools plugins you need a Download Package. Get it with virtual coins that you receive for forum activity or Buy Download Package - We have a zero Spam tolerance so read our forum rules first.

    Buy Download Package Now!
  2. Do not try to cheat our system and do not post an unnecessary amount of useless posts only to earn credits here. We have a zero spam tolerance policy and this will cause a ban of your user account. Otherwise we wish you a pleasant stay here! Read the forum rules
  3. We have a few rules which you need to read and accept before posting anything here! Following these rules will keep the forum clean and your stay pleasant here. Do not following these rules will lead to permanent exclusion from this website: Read the forum rules.

Writing a motion cueing software from scratch.

Discussion in 'DIY Motion Simulator Projects' started by Dirty, Feb 28, 2019.

  1. hexpod

    hexpod http://heXpod.xyz Gold Contributor

    Joined:
    Apr 18, 2016
    Messages:
    215
    Location:
    berlin
    Balance:
    1,568Coins
    Ratings:
    +77 / 0 / -0
    My Motion Simulator:
    DC motor, 6DOF
    @value1 , Thanks for your clarification.

    I have to admit that my experience with racing games is pretty limited, I simply see so many people fighting to feed correctly their yaw.

    You could maybe do some pedagogy, explaining more in details what the “traction loss” coming from some games is?

    I am sure this could help people to use the data more appropriately and help the development by finding the eventual bugs .

    In my case, x-plane provides angular velocieties. So I am skipping the useless “yaw position data” from the telemetry plugin. Using only the yaw velocity on the yaw, do the job perfectly in my case.

    Best
    Last edited: Mar 5, 2019
  2. pmvcda

    pmvcda aka FlyPT

    Joined:
    Nov 3, 2010
    Messages:
    330
    Location:
    Portugal
    Balance:
    2,506Coins
    Ratings:
    +375 / 2 / -0
    My Motion Simulator:
    6DOF
    The code for a fast one:
    (that's part of my code)
    Code:
           
    
            private ClassPoint3D centerOfRotation = new ClassPoint3D(0, 0, 0);
            private double cy, sy, cr, sr, cp, sp;
            private double qw, qx, qy, qz;
            private double n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12;
    
    
            // ==============================
            // Precalculation of quaternation
            // ==============================
            public void prepareTransform()
            {
                // Pre calculate quaternation...
                cy = Math.Cos(poseFilteredValue[YAW] * HALF_DEG_TO_RAD);
                sy = Math.Sin(poseFilteredValue[YAW] * HALF_DEG_TO_RAD);
                cp = Math.Cos(poseFilteredValue[ROLL] * HALF_DEG_TO_RAD);
                sp = Math.Sin(poseFilteredValue[ROLL] * HALF_DEG_TO_RAD);
                cr = Math.Cos(poseFilteredValue[PITCH] * HALF_DEG_TO_RAD);
                sr = Math.Sin(poseFilteredValue[PITCH] * HALF_DEG_TO_RAD);
                qw = cy * cp * cr + sy * sp * sr;
                qx = cy * cp * sr - sy * sp * cr;
                qy = sy * cp * sr + cy * sp * cr;
                qz = sy * cp * cr - cy * sp * sr;
                n1 = qx * 2f;
                n2 = qy * 2f;
                n3 = qz * 2f;
                n4 = qx * n1;
                n5 = qy * n2;
                n6 = qz * n3;
                n7 = qx * n2;
                n8 = qx * n3;
                n9 = qy * n3;
                n10 = qw * n1;
                n11 = qw * n2;
                n12 = qw * n3;
            }
    
    
            // =========================================
            // Transforms a 3D point to the current pose
            // =========================================
            // To be used after prepareTransform()
            public ClassPoint3D transformPoint(ClassPoint3D point)
            {
                return new ClassPoint3D(
                    (1 - (n5 + n6)) * (point.x - centerOfRotation.x) + (n7 - n12) * (point.y - centerOfRotation.y) + (n8 + n11) * (point.z - centerOfRotation.z) + poseFilteredValue[SWAY] + centerOfRotation.x, 
                    (n7 + n12) * (point.x - centerOfRotation.x) + (1 - (n4 + n6)) * (point.y - centerOfRotation.y) + (n9 - n10) * (point.z - centerOfRotation.z) + poseFilteredValue[SURGE] + centerOfRotation.y,
                    (n8 - n11) * (point.x - centerOfRotation.x) + (n9 + n10) * (point.y - centerOfRotation.y) + (1 - (n4 + n5)) * (point.z - centerOfRotation.z) + poseFilteredValue[HEAVE] + centerOfRotation.z
                    );
            }
  3. Dirty

    Dirty Active Member Gold Contributor

    Joined:
    Oct 15, 2017
    Messages:
    111
    Occupation:
    All the way up front.
    Location:
    Germany
    Balance:
    1,253Coins
    Ratings:
    +120 / 1 / -0
    :grin Yes, those "cos-sin-cos-sin-cos-sin" and "w-x-y-z" groups look traumatically familiar! Thank you for posting, I will try to make sense of it.

    I guess that I could've eventually found a way to apply those formulae in a somewhat useful manner, but I have this naive expectation of wanting to understand things before I apply them. After all, if I actually use your code without understanding it, I would have absolutely no way to troubleshoot problems later on without your help :(
    Last edited: Mar 6, 2019
  4. Dirty

    Dirty Active Member Gold Contributor

    Joined:
    Oct 15, 2017
    Messages:
    111
    Occupation:
    All the way up front.
    Location:
    Germany
    Balance:
    1,253Coins
    Ratings:
    +120 / 1 / -0
    Thanks for sharing @value1. Interesting quote form your professor! Just a few weeks ago I often thought, "well I can simply differentiate that" but I had to learn that with discrete time signals, that is not quite as straight forward. So my approach to that problem so far was trying to grab the data as far up the "differentiation ladder" as possible (if that makes sense) and then integrate down from there. I rather use yaw rate (omega_vert) than yaw. I rather use acceleration then velocity.

    The "core"motion data I'm using is (all in vehicle reference system)
    -Accel_x
    -Accel_y
    -Accel_z
    -Omega_x
    -Omega_y
    -Omega_z.

    ...and to be honest, I wouldn't know what more to ask for. All the other data I use is just for "effects" (AOA, IAS, MACH, GS, HGT).

    I am reasonably certain, that X-Planes dataRefs leave no desires unfulfilled when it comes to exporting motion data. MSFS/P3D should be similar. I'd be very much surprised if there were ANY data unavailable for export.

    Dirty:D
  5. Dirty

    Dirty Active Member Gold Contributor

    Joined:
    Oct 15, 2017
    Messages:
    111
    Occupation:
    All the way up front.
    Location:
    Germany
    Balance:
    1,253Coins
    Ratings:
    +120 / 1 / -0
    OK, I said I'd show you what I have been doing so far.

    A little primer video on DCS Worlds export function:



    ...and then a little something on how to read that exported data via the network.



    For a short time I used a WinFormApp to process the data, but realised that it would give me only limited options to develop unless I could get it to give me a 3D graphical representation. Something that might sound trivial to some of you, but to me, that was the greatest hindrance I encountered so far. The program also had a memory-leak that I didn't even care to fix :) But I learned a lot from it!



    Eventually I (ab)used Unity engine to get something in 3D and it gave me all the tools I needed to continue. Yes, I'm still not quite over this whole "quarternion-fiasco", but I am reasonably certain, that I can let Unitys developers take care of those and simply use functions like AddForce() Move() AddMoment() SetPosition() etc... etc... to move the upper platform.



    And here a little outlook on how I would love to see a motion cueing software to work: I am using the Unity editor, but maybe I can implement something like this directly in the UI for the user to throw together different components in a more intuitive way.



    Cya,...
    Dirty :D
    • Like Like x 4
  6. hexpod

    hexpod http://heXpod.xyz Gold Contributor

    Joined:
    Apr 18, 2016
    Messages:
    215
    Location:
    berlin
    Balance:
    1,568Coins
    Ratings:
    +77 / 0 / -0
    My Motion Simulator:
    DC motor, 6DOF
    very promising all-in-one. brilliant!
  7. cfischer

    cfischer Member Gold Contributor

    Joined:
    Sep 7, 2015
    Messages:
    66
    Location:
    Colorado
    Balance:
    523Coins
    Ratings:
    +26 / 0 / -0
    Think of the implications for motion cancelation in vr too!
  8. Dirty

    Dirty Active Member Gold Contributor

    Joined:
    Oct 15, 2017
    Messages:
    111
    Occupation:
    All the way up front.
    Location:
    Germany
    Balance:
    1,253Coins
    Ratings:
    +120 / 1 / -0
    You mean, using the motion data directly from out of the motion cueing software to cancel out the unwanted motion in VR?

    That idea is not specific to my design, but should apply to any motion cueing software in general, I think. Initially that Idea might sound appealing (and it certainly did to me when I first read about it a few months ago), but after a closer look it has some flaws: You need to cancel out the ACTUAL motion of the platform, not just the commanded motion. The software only knows where it WANTS the platform to be, but doesn't get feedback how well the PID loop in the controller manages to follow that command.

    I was able to try out "conventional" motion cancellation (with a hijacked Vive controller) on @apointner 's 360° tumble-dryer of a rig and I was completely blown away how smooth it works. It absolutely cancels out all unwanted motion. And that was 360° rolls at rates of up to ~200°/s .

    Theoretically you are right, and I would love to see someone try this out!
    • Like Like x 1
    • Agree Agree x 1
  9. Dirty

    Dirty Active Member Gold Contributor

    Joined:
    Oct 15, 2017
    Messages:
    111
    Occupation:
    All the way up front.
    Location:
    Germany
    Balance:
    1,253Coins
    Ratings:
    +120 / 1 / -0
    Reference Systems (CoordinateSystems)

    Imagine this scene:
    Woman enters the hallway. Groceries on her arm. She shouts through the house „Honey, I'm home. I bought you Hall sensors and linear bearings“.
    Voice from the off: „Great!“
    She: „Where are you?“
    He: „Here!“
    She: „Where is here?“
    He: „In the West Wing, second floor, third door on the right, in the simulator workshop that you and your Mum built me for my birthday, remember? Right between the electronics component storage and your table dance exercise room“.

    …ya know,… the typical everyday couple conversation.

    What you should take away from this scene is the idea, that „here“ is not a position. Neither is „on the chair“ or „in front of the desk“, unless you and the person you're talking to are using the same reference system (in this case: knowing which room we are talking about) It is only when he references his position relative to the house, that she knows where he is. The house is the only common reference system they are both sure to be in.

    Whenever you want to describe a position (or motion) technically, you will have to make sure that there is absolutely no doubt about which reference system is being used. After all, the position information is nothing but „go this number of units in the X-direction, and this number of units in the Y-direction“. For that to make any sense at all, we first have to agree on where the origin is, and which direction the X and Y direction is.


    Another concept that I hope you can embrace is the fact that reference systems themselves can be defined within parenting reference systems. Like, on a cruise ship, you can define your position by saying I'm at the bow/stern, port or starboard. And that makes perfect sense to someone on the cruise ship with you.

    However, if you need the actual precise geographical location (because your buddy wants to beam down from Starship Enterprise), then you will need to know where exactly on the globe that cruise ship is and how it's oriented. You will have to define the reference system of the cruise ship within the reference system of the earth.
    Bildschirmfoto 2019-03-09 um 10.59.38.png

    So, take away these two key concepts:
    1. Position information only makes sense within a reference system
    2. Child reference systems can be defined within a parenting reference systems

    For our particular case, those would be the „World Coordinate System“ (WCS) and the „Platform Coordinate System“ PCS. To keep those well separated I will call the WCS coordinates x-y-z and the PCS coordinates u-v-w. Similarly I will call the rotation rates around these axes Wx-Wy-Wz and Wu-Wv-Ww. „W“ being the greek letter „Omega“ which is normally used for angular rates.
    Last edited: Mar 9, 2019
  10. Dirty

    Dirty Active Member Gold Contributor

    Joined:
    Oct 15, 2017
    Messages:
    111
    Occupation:
    All the way up front.
    Location:
    Germany
    Balance:
    1,253Coins
    Ratings:
    +120 / 1 / -0
    The hovering platform

    Writing code is representing real world objects with computer memory objects. But before we can represent anything in computer memory, we should have a crystal-clear picture of what it is we want to represent. What are we even doing in 6DOF motion simulation? I think that is a question worth asking!

    The image of the „hovering platform“ was what made it „click„ for me:

    Imagine your upper platform was hovering weightlessly in the room. Exactly in its neutral position. Surge, Sway and Heave are exactly in their zero positions and Yaw, Pitch and Roll are all zero as well. The rig doesn’t have actuators. You are the one moving it around through telekinesis :)

    Now, the question comes up: „How do you move it?“

    For most of you that question never came up before, because it was answered already by the one writing the 6DOF plug-in. You have been using terms like Sway, Pitch and Roll but never asked yourself the question: „What does it mean to move something in Sway? Where is Sway pointing? What reference system is it defined in“?
    The world coordinate system? The platform coordinate system? Or any of the arbitrary number of further coordinate systems we can (and will!) stack on top of those?
    • Informative Informative x 2
  11. hexpod

    hexpod http://heXpod.xyz Gold Contributor

    Joined:
    Apr 18, 2016
    Messages:
    215
    Location:
    berlin
    Balance:
    1,568Coins
    Ratings:
    +77 / 0 / -0
    My Motion Simulator:
    DC motor, 6DOF
    Because usually in the IK the rotations are independent from translations it’s rather “world” than “platform”

    Sway will be always perpodicular to the absolute longitudinal axis regardless how the platform is tilted
  12. Dirty

    Dirty Active Member Gold Contributor

    Joined:
    Oct 15, 2017
    Messages:
    111
    Occupation:
    All the way up front.
    Location:
    Germany
    Balance:
    1,253Coins
    Ratings:
    +120 / 1 / -0
    Yes! That's great! Exactly what I was hoping you'd say!

    It might seem trivial to some (certainly you), but for quite a while I was stuck, because I just assumed there to be only one reference system (World) and also assumed, that sway/heave/surge were defined in x/y/z cardinal directions. So I thought of how I would correct those directions for yaw/pitch/roll. Of course, a dead-end road!

    In school, and later on in my professional training, I was introduced to the subject of manipulating objects in space always in the convention of an "x/y/z/yaw/pitch/roll" order. And it made sense to do so.

    But here, this order has to be changed, or we will run into problems. And in fact, I think we might need more than 6 transformations.
  13. hexpod

    hexpod http://heXpod.xyz Gold Contributor

    Joined:
    Apr 18, 2016
    Messages:
    215
    Location:
    berlin
    Balance:
    1,568Coins
    Ratings:
    +77 / 0 / -0
    My Motion Simulator:
    DC motor, 6DOF
    Nothing is trivial man, I recall getting cerebral diarrhea when I tried to get right the drawing in openGL And that’s only basics.

    Right hand, left hand coodinate system and so on.
    https://docs.microsoft.com/en-us/windows/desktop/direct3d9/coordinate-systems

    If you studied it you are certainly more advanced than me.

    I have the feeling that there is no absolute standard, and you may notice small variations how the game developers are dealing with their coordinate system.

    Maybe @value1 can say something as he has big experience with telemetry.

    Good luck man, you can do it!
    Last edited: Mar 9, 2019
  14. hexpod

    hexpod http://heXpod.xyz Gold Contributor

    Joined:
    Apr 18, 2016
    Messages:
    215
    Location:
    berlin
    Balance:
    1,568Coins
    Ratings:
    +77 / 0 / -0
    My Motion Simulator:
    DC motor, 6DOF
    Quote: 39533A8F-3CB7-4457-99F0-B9E8A47DF31E.jpeg 691A8585-675E-4563-9FF7-98D8E4D38FEC.jpeg I mean, your interrogation is absolutely right. I remember, recently we had a hard time to sort out the telemetry of x-plane because what you find in the documentation doesn’t seems to correspond what you find in the game.

    https://www.x-plane.com/kb/data-set-output-table/

    Austin talking about the forces: go to 24min 10s.
    https://m.facebook.com/story.php?story_fbid=1493547950669175&id=442899392400708&_rdr

    After all @value1 just subtracted the earth accel on the heave (-1) which seems to work well.
    • Agree Agree x 1
  15. Dirty

    Dirty Active Member Gold Contributor

    Joined:
    Oct 15, 2017
    Messages:
    111
    Occupation:
    All the way up front.
    Location:
    Germany
    Balance:
    1,253Coins
    Ratings:
    +120 / 1 / -0
    Hey :)

    Did you find anything wrong with X-Planes representation of G-Load? Or found it unsuitable for use in motion Sims? Or did I misunderstand?

    I will confirm when I get back home, but last time I looked at it, I saw nothing wrong with it.

    Here's how I think it works in a nutshell:
    1. Add up all the forces on the aircraft (without gravity) into one resulting vector.
    2. Split this vector up into its Lon/Vert/Lat components (vehicle reference system).
    3. Divide by total mass, to turn force [kg*m/s^2] into acceleration [m/s^2]
    4. Divide by 9.81 m/s^2/G. To turn acceleration into G-Load [G]

    That's what the values of G-Load axial/normal/side represent. It is what an occupant would feel.

    If you want to determine the rate of change of the vehicle trajectory, you will have to
    1. Add up the vectors of all forces on the aircraft (Now including gravity!).
    2. Divide by mass. The result is in [m/s^2].


    Did it really make a difference when you subtracted 1? I was planning on using G-load (Accel_Vert) on heave only after a highpass filter. So the steady 1 would not be present in the filtered signal anyways.

    Can you describe what was "wrong" before you subtracted 1?

    Dirty :)
  16. Tim McGuire

    Tim McGuire "Forever a work in progress"

    Joined:
    Jul 26, 2015
    Messages:
    257
    Occupation:
    Electrical/Electronics Engineer
    Location:
    Canada
    Balance:
    1,908Coins
    Ratings:
    +300 / 1 / -0
    My Motion Simulator:
    3DOF, DC motor
    Great thread! I like the thorough approach. Fellow EE by any chance?
  17. Dirty

    Dirty Active Member Gold Contributor

    Joined:
    Oct 15, 2017
    Messages:
    111
    Occupation:
    All the way up front.
    Location:
    Germany
    Balance:
    1,253Coins
    Ratings:
    +120 / 1 / -0
    I take that as a giant compliment! Thanks!

    EE = electrical engineer? No, unfortunately not. :( First time I read the word "H-Bridge" I thought the guy (an Australian) must be talking about the Sydney Harbor Bridge. Seriously!

    I was thinking not too long ago, that this hobby would require a mechanical engineer, an electrical engineer and a computer scientist working together.

    My education is somewhat strange. I barely made it through school, but I excelled at Physics. I got a prestigious scholarship from a huge company to study aeronautical engineering (on their payroll!) at the University of Stuttgart without even preparing tor the test. I turned that down when another company offered a similarly prestigious program in pilot training.

    Really all I can produce as qualification is that I am rock solid when it comes to physics, I have a vivid imagination (to say the least) and plenty of time in the hammock to think things through :)
    Bildschirmfoto 2019-03-10 um 11.30.37.png


    :cheers
    • Like Like x 1
  18. joe extraknow

    joe extraknow Member Gold Contributor

    Joined:
    Jan 4, 2017
    Messages:
    86
    Location:
    United States
    Balance:
    1,238Coins
    Ratings:
    +27 / 2 / -0
    My Motion Simulator:
    3DOF
    The platform moving sway/surge/.....is reference to the world. You sit on the platform can be referenced to platform (local). This is how the Equivalence principle works.
    Say for free-fall airplane, you feel zero-gravity, this is due to Equivalence Principle.
    You in an elevator which is free fall down with acceleration downward in g as in world reference. You feel zero g (no motionat all) in local reference. I see 6dof users usually use sway in a world reference way. In theory, if one likes to feel a true lateral g force, the sway direction shall be opposite to the g direction one feels (local reference). For braking/acceleration, seems all they did right using surge with local reference.

    Btw, here is the 6dof video shown using 10 computers, claimed to simulate g-effect in 98% accurately up to 2g. Is this sort you are trying to do?

    Last edited: Mar 10, 2019
  19. hexpod

    hexpod http://heXpod.xyz Gold Contributor

    Joined:
    Apr 18, 2016
    Messages:
    215
    Location:
    berlin
    Balance:
    1,568Coins
    Ratings:
    +77 / 0 / -0
    My Motion Simulator:
    DC motor, 6DOF
    Simtools needs we define max. and min. to scale the variable on a deg-of-freedom. Value 0 is needed to center the axis while the object is not moving.

    When the aircraft is not moving xplane g-normal outputs value 1, which is logical.

    That was lifting the heave regarding to scaling factor, eating almost all the workspace of the platform.

    I don’t know if it’s the best way to proceed but as I said subtracting 1 did the job.
  20. hexpod

    hexpod http://heXpod.xyz Gold Contributor

    Joined:
    Apr 18, 2016
    Messages:
    215
    Location:
    berlin
    Balance:
    1,568Coins
    Ratings:
    +77 / 0 / -0
    My Motion Simulator:
    DC motor, 6DOF
    I tried @yobuddy ‘s “washout” filter to bring the heave to the center but without any success.

    I reported broken filter issue months ago asking for debug.