1. Do not share user accounts! Any account that is shared by another person will be blocked and closed. This means: we will close not only the account that is shared, but also the main account of the user who uses another person's account. We have the ability to detect account sharing, so please do not try to cheat the system. This action will take place on 04/18/2023. Read all forum rules.
    Dismiss Notice
  2. 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 Now a Download Plan!
  3. 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
  4. 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. Do not follow these rules can lead to permanent exclusion from this website: Read the forum rules.
    Are you a company? Read our company rules

Writing a motion cueing software from scratch.

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

  1. Dirty

    Dirty Well-Known Member Gold Contributor

    Joined:
    Oct 15, 2017
    Messages:
    744
    Occupation:
    All the way up front.
    Location:
    Germany
    Balance:
    7,905Coins
    Ratings:
    +877 / 3 / -0
    Spot on! In motion cueing we are exploiting humans susceptibility to somatogravic and somatogyral illusion to our advantage :)
    Last edited: May 7, 2019
  2. hexpod

    hexpod http://heXpod.xyz

    Joined:
    Apr 18, 2016
    Messages:
    1,185
    Location:
    berlin
    Balance:
    7,636Coins
    Ratings:
    +369 / 5 / -0
    My Motion Simulator:
    DC motor, 6DOF
    Thanks for the wiki link.

    Very informative !
  3. hexpod

    hexpod http://heXpod.xyz

    Joined:
    Apr 18, 2016
    Messages:
    1,185
    Location:
    berlin
    Balance:
    7,636Coins
    Ratings:
    +369 / 5 / -0
    My Motion Simulator:
    DC motor, 6DOF
    Dreaming dreaming ....

    Native xplane motion algorithm AND VR motion cancellation.

    Certainly doable. 6-variables and that’s it. Headset On, and ready for a real ride.

    Let’s hope that Ben’s “not ASAP” doesn’t hold on ground something which could be the best idea ever!
  4. yobuddy

    yobuddy Well-Known Member Staff Member Moderator SimAxe Beta Tester SimTools Developer Gold Contributor

    Joined:
    Feb 9, 2007
    Messages:
    5,282
    Occupation:
    Computer Technician
    Location:
    Portland, Oregon - USA
    Balance:
    49,206Coins
    Ratings:
    +5,093 / 18 / -0
    Hi Dirty,
    Hope you are well man. I love chatting new ideas! It's the fun part for me buddy.
    My worry is I don't want to break the way we are doing things currently, or so many people may be lost.
    A few people would have sims that won't work they way they want to anymore.
    Or a roller coaster sim where we can't make it tip the whole time as wanted.

    But SimTools is built so one person can do things one way without affecting the next person.
    So there is no reason we can make alternate plugins.
    That's what I meant above actually.
    ~ Lets go over you suggestions buddy. ~
    1)
    I would love to go over all this anytime buddy.
    Maybe form a group chat?

    2)
    Not really, if you mean you want more Min / Max columns.
    But we can premix anything we want in the game plugin itself and then export the normal 9 outputs as usual.

    The more outputs we have in the software thou, means the more the software and the PC has to do, and the harder axis assignments plugins could be to make.
    So striking a balance can be tricky for sure.
    But SimTools will just keep evolving as there is a need, version v2.4 will be a huge jump forward for sure.

    3)
    Yes, this is no problem.
    And with v2.4 there are no limitations on what goes where, meaning weather you send Euler Angles, or degrees or accelerations all the filters will work as usual.

    Chat soon! :thumbs
    Take care,
    yobuddy
    • Like Like x 1
    • Friendly Friendly x 1
  5. Dirty

    Dirty Well-Known Member Gold Contributor

    Joined:
    Oct 15, 2017
    Messages:
    744
    Occupation:
    All the way up front.
    Location:
    Germany
    Balance:
    7,905Coins
    Ratings:
    +877 / 3 / -0
    And here a quick look into the ground model. I have spent virtually no time on tuning that so far.
    The key point of that video is that I will use two different sets of gains and offsets for flight and ground. Tuned independent from each other and then fade over from one to the other within ~2 seconds after touchdown.

    • Like Like x 1
  6. apointner

    apointner Siddhartha

    Joined:
    Aug 16, 2014
    Messages:
    63
    Location:
    N 48° 9'0.88" E 12° 5'45.84"
    Balance:
    764Coins
    Ratings:
    +17 / 3 / -0
    My Motion Simulator:
    3DOF, DC motor, Arduino, Motion platform
    i am builded a 360° 3DOF Full Sim and hope to clear some things out.
    And i had the pleasure to fly in LEVEL D Full Flight Simulator:
    https://www.xsimulator.net/communit...professional-flight-simulators-level-d.13739/
    Plus some RL exp. with A-320, Aerobatics in Yak-52, Gliders and Paragliding.

    After many testing and tweaking with my 360° Pit i must confirm what @Dirty points out.
    Forget about Euler Position to simulate constant Gs. E.G. in aerobatics i only feel two things:

    1. pos / neg Gs: It´s all about that, imho. By far the strongest force and the most important Value to get a realistic feeling. How to do? Later...#1

    2. Rapid changes in Roll,Pitch,Yaw,Side: If you throw the stick full right, your head may bangs on the canopy...but only for a second *g.
    After this first "kick" even a steady 200° roll feels smooth to me, nearly no forces at all.

    Some would say, and what´s about constant acc/decc?! This is something special...+ 0.8 G acc is enough to make Humans screaming like childs.
    But in compare to the huge pos Gs, it´s just a joke. So, yes we have to simulate this force cause our brain reacts very sensitive to it (see #2)

    So how feels aerobatics in a 360° Sim?

    Ok i could say, hey i have a 360° Pitch axis, that simulates the RL Pitch behavior perfect!

    Nope, it isn´t.
    Couse you don´t feel the Pitch Up in RL. You only feel that minium of 3 positive Gs pressing you and your innards into the seat. However flying a constant Pitch Angel is perfectly simulated with 360° :)

    But hey, i can easly simulate a constant 360° Roll with 220°/sec, right?!
    Hmm, let´s say it depends on the Airplane:
    In RL the AC has to overcome the centrifugal force while doing a roll. So the Pilot is pulling the Stick a bit, this generates...positive Gs again.
    But in most Jets the Pilot is placed above the (turning) Planeaxis. This generates much negative centrifugal G Forces, which balances the mentioned positive Gs.


    #2 What about Accelartion/Decc Forces?

    Since you don´t need much force to generate a realistic feeling, i choosed pitch to simulate the constant acc/decc.
    Kicking in the Burner feels just amazing real (Pitch up +8°)! Same with airbrakes.
    But while doing a carrier launch the Pitch Axis goas up +80° (represents +0.8G acc)
    This is for sure a amazing roler coster effect and the result is close to RL Gs, but it feels wrong, because you´ll still note the pitch upward acceleration!
    Same with carrier landings. So, this is just a compromise.
    When flying invertet, i reverse this effekt to stay real at least.
    A 6DOF Hexas can simulate Acc/Decc better.


    What about slipping (Yaw/Sway)?
    I use bank to simulate this, witch works in some cases well.
    But the Bankangle is max +/- 15° to generate sway. More angle is not possible without braking immersion (see #2).
    Now imagine what happens when flying right 30° Bank and apply full left rudder.
    The result feels like a little slide to the right, but in RL Life you would feel a force pulling you to the left.
    So Sway/Yaw is much better simulated with a 6DOF Hexa.

    Ok, then what about a constant 60° Bank turn?
    Worst thing. In RL you mostly feel...right, positive Gs.
    But in my (banked) Pit it feels like a 0.5G sideslip.
    Luckly i have a solution for this, and so it feels amazing! See #1.

    Errrrr, and then what about level or invert flight!?
    Yes ok , this feels just perfect like RL :)

    You see 360° is not the better solution for Motion Simulation.
    BUT...


    #1
    To overcome the pos/neg G Problem you can build a heave axis with 50cm travel or more.
    This is enough for soft civ flights, since you feel the rapid changes in all Dimension far more, then the lower constant Forces.

    But as soon you do a little more aerobatics or mill. flight the pos Gs are just insane and dominate everything.
    So we need to simulate CONSANT pos Gs!
    Out of options with my 2DOF i stumble over the Berginson Seat - this is the way to go!
    But i didn´t had the time to build the hole seat - and i just needed the heave Axis anyway.
    So for testing i just connected the belt buckle (from the 5point belt) with a cable to a geared DC Motor.
    And wow!!
    The pure pressure of 80Nm is distributed cleanly on shoulders, chest, thighs and pelvis.
    You can hardly feel that in reality a pull in the middle is the source of the Gs.
    Each G is noticeable, even at fast rashes during take off.
    At max. Gs i almost lose the air, although the objective pressure on the body is only a fraction of the real Gs.
    Only with the belt tension the 360° Simulator is damn close to real life!
    However i don´t know how cool it would be with the hole system from berginson.
    For example i could imagine that Acc/Dec/Sway/Yaw is way better simulated with the bergison solution.

    Conclusion: no matter what system you plan...solve the pos G problem. Everthing else is minor.

    So why the hack go for 360°?!

    Most people here forget about on important thing:
    The sense of balance!
    Even when you don´t feel constant Gs on your Body while doing a roll at 200°/sec, your Ears and Eyes will tell you : WTF!!!
    E.g. you could easly put a belt-tension system for positive Gs in a 6DOF Hexapod, and still it can´t provide the same thrill, because of angle limitations.
    Especially with VR it is scary like RL flying. My first real life loop scared me in the same way this simulator did !
    And in the End of the Day it is exhausting - this simulator gives you a small clue what real fighterpilots must accomplish.


    Ok that´s it, i hope this offers some new aspects to this topic and pls don´t blame me for bad english :)
    • Like Like x 1
    Last edited: Aug 26, 2019
  7. SeatTime

    SeatTime Well-Known Member

    Joined:
    Dec 27, 2013
    Messages:
    2,573
    Occupation:
    Retired
    Location:
    Brisbane Australia
    Balance:
    28,370Coins
    Ratings:
    +2,844 / 39 / -0
    My Motion Simulator:
    AC motor, Motion platform
    Yep all true and it is why I use a G-vest in my own sim :).
    • Winner Winner x 2
  8. apointner

    apointner Siddhartha

    Joined:
    Aug 16, 2014
    Messages:
    63
    Location:
    N 48° 9'0.88" E 12° 5'45.84"
    Balance:
    764Coins
    Ratings:
    +17 / 3 / -0
    My Motion Simulator:
    3DOF, DC motor, Arduino, Motion platform
    Yes, i must say...the vest is a very good idear. I saw some pictures somewhere here, wired with cabels and linked with the harness. The Head, too. Hm, could fit into my Pit...hmmm. Thanks!
  9. harwoodr

    harwoodr New Member

    Joined:
    Dec 9, 2013
    Messages:
    28
    Balance:
    441Coins
    Ratings:
    +11 / 0 / -0
    My Motion Simulator:
    Motion platform, 6DOF
    So I'm at the point with the (simple) MCA I'm doing for my project where all the classical expected output is being produced (yay!)... and I'm trying to wrap my head around "return to neutral" false cues and how to deal with that. (If anyone has any pointers or links - advice is appreciated)

    mca.png
    In any case, I'm going to move forward with this for now and plug in my inverse kinematics next... well, that and fix a sticky solenoid valve, but some silicone lubricant can fix that... ;)

    After that, I'm going to collect some force data from simtools/no limits roller coaster 2 and run it through the software and see how it looks/ performs.

    I might quickly throw a simulated simulator into my python code using pyQTgraph... we'll see.
    • Like Like x 2
  10. Dirty

    Dirty Well-Known Member Gold Contributor

    Joined:
    Oct 15, 2017
    Messages:
    744
    Occupation:
    All the way up front.
    Location:
    Germany
    Balance:
    7,905Coins
    Ratings:
    +877 / 3 / -0
    Hey there :)
    Nice curves! Trying to build something like this as well to look at the data in real time. So far, I can only log the data and later visualise it in Excel.
    A question about the highpass signal: How do you create that? It is apparently not being created by subtracting the LP-signal from the original signal. Do you have a code snippet? I'm asking because from the looks of it, it should give exactly the kind of motion response I would like to see for a step input.

    And on top: It looks as if THIS is the kind of signal that would actually work nicely with an integrator instead of another LP filter (you remember our conversation?)

    Thumbs up!! :thumbs

    Dirty :)
  11. Dirty

    Dirty Well-Known Member Gold Contributor

    Joined:
    Oct 15, 2017
    Messages:
    744
    Occupation:
    All the way up front.
    Location:
    Germany
    Balance:
    7,905Coins
    Ratings:
    +877 / 3 / -0
    Not sure if that makes sense to anyone outside my own head: The fact that this signal integrates to zero before the step reversal (area below = area above) makes it so appealing to me. This is what I need! :!

    Dirty :)
  12. Dirty

    Dirty Well-Known Member Gold Contributor

    Joined:
    Oct 15, 2017
    Messages:
    744
    Occupation:
    All the way up front.
    Location:
    Germany
    Balance:
    7,905Coins
    Ratings:
    +877 / 3 / -0
    On another note: I've started to populate the GUI of my software, so that a user can eventually use the software :)
    Bildschirmfoto 2019-05-12 um 20.31.07.png

    Up until now, I have made all changes directly in code or inside the Unity editor.
  13. harwoodr

    harwoodr New Member

    Joined:
    Dec 9, 2013
    Messages:
    28
    Balance:
    441Coins
    Ratings:
    +11 / 0 / -0
    My Motion Simulator:
    Motion platform, 6DOF
    So, I'm using python to generate that... and a couple of libraries (numpy and scypi) to do the heavy lifting... I'll send you a copy of the code.

    In the mean time - when I want to generate a filter, I use a class (that I stole) that gives me a few functions on top of a filter (init, reset and apply - the last of which is "take this new data value and stuff it in the filter"). To instantiate that class with a specific type of filter, I do this:

    #low pass filter - first order
    def firstlp_filter(w):
    b= [0,w]
    a= [1,w]
    return RealtimeFilter(*signal.bilinear(b,a,fs=FREQ))

    Which translates to omega/(s+omega)... or:

    #high pass filter - second order
    def secondhp_filter(z,w):
    b=[1,0,0]
    a=[1,2*z*w,w**2]
    return RealtimeFilter(*signal.bilinear(b,a,fs=FREQ))

    Which translates to s^2/(s^2+2*zeta*omega*s+omega^2)...

    Here's the fun part... want an integral function?

    #single integrator - 1/s
    def sint_filter():
    b= [0,1]
    a= [1,0]
    return RealtimeFilter(*signal.bilinear(b,a,fs=FREQ))

    ...a double integral?

    #double integrator - 1/s**2
    def dint_filter():
    b= [0,0,1]
    a= [1,0,0]
    return RealtimeFilter(*signal.bilinear(b,a,fs=FREQ))

    ...which I just corrected, so, thanks - posting helped me see where I had a bug. lol
    • Like Like x 1
  14. harwoodr

    harwoodr New Member

    Joined:
    Dec 9, 2013
    Messages:
    28
    Balance:
    441Coins
    Ratings:
    +11 / 0 / -0
    My Motion Simulator:
    Motion platform, 6DOF
    Hmm, so I'm playing with tilt coordination... and comparing input forces against effective output forces... x and y are good... but z is off... Now, yes, I know, there's no actual tilt coordination in the z axis (as yaw doesn't affect it)... but doesn't tilting take away the effect of gravity on the z axis (while adding it to the x and y axes)?

    So if I'm pitched 30 degrees, the effect on the x axis is 1G* cos(30)... wouldn't I lose a corresponding value on the z axis?
  15. Dirty

    Dirty Well-Known Member Gold Contributor

    Joined:
    Oct 15, 2017
    Messages:
    744
    Occupation:
    All the way up front.
    Location:
    Germany
    Balance:
    7,905Coins
    Ratings:
    +877 / 3 / -0
    That's the magic of trigonometry :)

    Indeed, it does so! :) Do you want me to say it straight out or should I leave you the fun of finding out for yourself? ;)

    From your text I figure that you use...
    x = longitudinal axis
    y = lateral axis
    z = vertical axis

    In the beginning we are untitled which means accel(z) is 1 while accel(x) and accel(y) are both zero. If you tilt the platform 30° around the lateral axis (y) then you generate an acceleration along the longitudinal (x) axis of sin(30°)., not cos(30°)!

    Accel(lon) = sin(30°)
    Accel(vert) = cos(30°)!

    Look at the graphs for a sine and a cosine, you will see that for small angles the sine value increases rapidly while the cosine looses barely anything. Only criteria that needs to be fulfilled is √(x^2+y^2+z^2) = 1

    ...same reason why cars that already use 86% of their available traction for turning can still use 50% of their available traction to accelerate :)

    Bottom line: Yes, we shift gravity away from Z onto X, but we get a lot more onto X than we take away from Z.

    ------------------------------------------------------

    btw. I got those filters working nicely, thanks for the code. Using an integrator now works like a charm. Not sure if it will introduce drift though. :)

    This is my backup plan:
    Bildschirmfoto 2019-05-13 um 22.24.08.png
    Grey for pitch and blue for surge. Assuming that the input step is an acceleration(Lon)

    Dirty :)
  16. harwoodr

    harwoodr New Member

    Joined:
    Dec 9, 2013
    Messages:
    28
    Balance:
    441Coins
    Ratings:
    +11 / 0 / -0
    My Motion Simulator:
    Motion platform, 6DOF
    Yeah, the more I look at it, the less I think that worrying about the loss of of G in z axis is worthwhile.

    So, blue is with the double integration and is effectively distance of the travel in the simulator? and grey is with single integration and is the angle of the platform?
  17. harwoodr

    harwoodr New Member

    Joined:
    Dec 9, 2013
    Messages:
    28
    Balance:
    441Coins
    Ratings:
    +11 / 0 / -0
    My Motion Simulator:
    Motion platform, 6DOF
    Okay, I've had some success with my motion cueing/kinematics...

    Video from my virtual simulator that I wrote today:



    Video of No Limits 2 - Crystal Beach Cyclone (the data from which is used in the first video):



    Cue the first to about 1:00 and the second to about 1:28 (that's where it gets interesting at least)... the blue line in the virtual simulator is the X-axis looking forward.

    I still have to do some tweaking on the filters/scaling... but this is very exciting for me...
    • Like Like x 2
  18. Dirty

    Dirty Well-Known Member Gold Contributor

    Joined:
    Oct 15, 2017
    Messages:
    744
    Occupation:
    All the way up front.
    Location:
    Germany
    Balance:
    7,905Coins
    Ratings:
    +877 / 3 / -0
    I guess I finally have something to try out for anyone who would like to take a look:

    Nutkicker Motion Control

    It is not pre-alpha or even prototype stage yet. I think "proof of concept" would best describe it. It reads the data from DCS (100% done), processes it (~50% done) and sends the actuator commands via serial connection to a controller (~10% done).

    So far, I only support DCS World but X-Plane and P3D will follow.

    Instructions:
    1. Copy the Export.lua file into your [Saved games folder]/DCS World/Scripts. Please save your existing Export.lua (if present).
    2. Start Nutkicker Motion Control Software.exe and acknowledge the warning.
    3. Click "Start Server"
    4. Start the sim. The data will flow when a mission is running and not paused.

    Keep in mind: There is still a lot to do! This is by no means intended to be actually used for motion cueing at this stage of development. PM me if you want to try it out in VR.

    I have a Mac version as well!

    Dirty :)
    • Like Like x 1
  19. Dirty

    Dirty Well-Known Member Gold Contributor

    Joined:
    Oct 15, 2017
    Messages:
    744
    Occupation:
    All the way up front.
    Location:
    Germany
    Balance:
    7,905Coins
    Ratings:
    +877 / 3 / -0
    Sorry, I phrased that totally stupid: That picture showed the filters as I use them NOW. I am about to make a few changes that I wasn't able to before.


    Before I talk about the integration, let me lay things out so that someone new to this has a chance to understand:

    Here's how a lowpass filter works:
    1. You pick a value between 0 and 1 that describes how much you want to smoothen out the signal. Let's call this value "alpha".
    2. To determine the output of your filter, let's assume that the current output of the filter at start time is 0 (zero).
    3. Whenever a "newInput" arrives, you calculate the "newOutput" of the filter by: newOutput = alpha * newInput + (1- alpha) * currentValue
    ...that's it. Your first Exponential Moving Average (EMA) filter :) basically you compose the newOutput with parts of the currentValue and parts of the newValue. How much of which, is determined by the value alpha. The higher that value, the higher the tendency of the filter to adopt the new value. I use values around 0.01 .

    If you send that signal through another LP filter, you have created a filter of 2nd order.
    If you send that signal through another LP filter, you have created a filter of 3rd order.
    If you send...

    ...you get the idea! :)

    Now, why would anyone want to send a signal, that has just been filtered, through the same filter yet again? Because it changes the characteristics of the signal in a quite important way. Each time, you add one level of "continuity".

    Here's the response to a step input of lowpass filters of different orders:
    Step LP.png

    The blue dotted line is the step input and please note that it is NOT continuous! It makes a step! Hence the name :) ...I guess.

    If I take that input value and send it through a lowpass filter, I get a LP filtered signal that is G0 continuous. Meaning each value "touches" its neighbour. It is not tangent, and certainly does not have the same curvature in that spot, but at least there are no more gaps.
    G0-Curve-Example.png

    If I take that output value and send it through another lowpass filter, I get a LP filtered signal that is G1 continuous. Meaning each value "touches" its neighbour, is tangent in that spot, but does still not have the same curvature in that spot, but at least there are no more corners.
    G1-Curve-Continuity.png

    If I take that output value and send it through yet another lowpass filter, I get a LP filtered signal that is G2 continuous. Meaning each value "touches" its neighbour, is tangent in that spot, and also has the same curvature in that spot. The curvature changes only gradually.
    g2-CURVE-CONTINUITY-1.png


    Take a look at that picture again:
    The yellow line has a corner. Curvature and change of curvature are infinitely high in that spot.
    The violett line has a radius. Curvature is present but moderate. Change of curvature (jerk) is still infinitely high.
    The green line builds up it's curvature gradually. Note that both curvature and the change of curvature are moderate.

    In this picture the gradient of the graph represents velocity, the curvature represents acceleration and the change of the curvature represents jerk. I will write about what humans can and cannot perceive next. So, once that is clear, it will become totally obvious why certain filters are chosen for certain DOFs.

    Basically it all boils down to the question of: "Do I want to make the occupant perceive something, or do I want to keep him from perceiving something"

    I'm gonna let that simmer for while :)

    Dirty :)

    Attached Files:

    • Like Like x 1
  20. Dirty

    Dirty Well-Known Member Gold Contributor

    Joined:
    Oct 15, 2017
    Messages:
    744
    Occupation:
    All the way up front.
    Location:
    Germany
    Balance:
    7,905Coins
    Ratings:
    +877 / 3 / -0
    HighPass filters.

    Let’s talk about high pass filters and how they react to a step input. First of all, I create a HPF by taking a low pass filtered signal and subtract it from the original signal (1-EMA). Whats left then is the high frequency content of that signal. You can still see the low pass filtered signal from the last post in this picture as the thin yellow line:
    Step HP.png

    The difference between this LP signal and the blue dotted input signal is the yellow dotted line. Note that it is NOT a continuous signal. It makes steps every time the input signal makes a step.

    If we send that signal through one or more low pass filters, we can change the properties of the signal exactly like we did in the previous post. Each time we add one level of continuity:
    1. No Continuity (yellow dotted) Signal has steps
    2. G0 continuity (grey) Signal has corners
    3. G1 Continuity (orange) Signals has radii
    4. G2 Continuity (not shown) Signal has curvature continuity

    Like in the last post, the gradient of the output graph still represents velocity, the curvature represents acceleration and the change of the curvature represents jerk.

    Which signal we use to drive which DOF depends on what we want the occupant to feel (or not feel). I will try to illustrate a concrete example in the next post.

    Dirty :)
    Last edited: May 25, 2019