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

My Custom 6 DOF VR Rig for Microsoft Flight Simulator

Discussion in 'DIY Motion Simulator Projects' started by Flying Pete, Dec 5, 2021.

  1. Flying Pete

    Flying Pete Member

    Joined:
    Mar 28, 2021
    Messages:
    13
    Location:
    Switzerland
    Balance:
    120Coins
    Ratings:
    +60 / 0 / -0
    My Motion Simulator:
    6DOF
    It's about time for me to present my 6 DOF motion rig. Quick backstory: I got into flight simming again end of 2020 (exclusively General Aviation). Then transitioned to VR, and realized it would be great to be able to actually feel the motion of the plane, to practice coordinated turns and the like. I looked into available options like seat movers, 2 DOF rigs, 6 DOF platforms... and then somehow came to the conclusion that I should build my own 6 DOF Stewart platform. I knew I wanted to go for a compact hexagonal design with rotary actuators, using 750W AC Servo Motors, but that was about it. I drew a lot of inspiration from motion4sim's work - his Motion4Sim Servo Motion Controller was one of the first items I bought for the build, and where everything started off. Also at this point, huge shoutout and thanks to motion4sim for all his help! Check out his build thread here: https://www.xsimulator.net/community/threads/6-dof-compact-sim-with-rotary-actuators.14894/. More info on the Motion4Sim controller: https://www.xsimulator.net/community/threads/new-6dof-aasd15-servo-motion-controller.15356

    When I started, I knew there would be several aspects on the hardware, software and controller side that I did not yet know how to solve, and some of which had never been solved before. But I started anyway, solving every issue along the way, and am now very happy with the result. It's hard to overstate the joy of flying in Microsoft Flight Simulator in VR with Full Motion: feeling the acceleration on takeoff, the roughness of the air, and being physically punished for a hard landing.

    I’m kicking off this build thread with some information on aspects that I consider to be relevant, split into four parts:
    • Part 1: The Rig - details about the overall design and mechanical and electrical aspects of the platform
    • Part 2: The Cockpit - what I decided to put on top of the platform and how I built it
    • Part 3: Control - how I drive the platform (motion cueing software and motion controller)
    • Part 4: VR - how I achieved motion compensation in Microsoft Flight Simulator using OpenXR/WMR and the HP Reverb G2

    My 6 DOF motion rig:
    10_fullrig.jpg
    • Winner Winner x 8
    • Like Like x 4
  2. Flying Pete

    Flying Pete Member

    Joined:
    Mar 28, 2021
    Messages:
    13
    Location:
    Switzerland
    Balance:
    120Coins
    Ratings:
    +60 / 0 / -0
    My Motion Simulator:
    6DOF
    Part 1: The Rig

    Mechanical:

    I designed the complete rig (base, platform and cockpit) in CAD, down to every single screw. The overall design was heavily inspired by motion4sim's 6 DOF platform, but instead of welding the base, I used item profiles (metric 80/20-style profiles, 40x40 and 80x40mm). Plus several custom-designed connecting parts that I had milled from aluminum and steel. My main vendor for this was Froelich AG https://www.froelichag.ch. The design contains several smaller 3D-printed parts (profile covers, crank arm end stops, etc…), which were printed on an Ultimaker 3. I also used 3D printing to prototype parts that would later be CNC-milled. I applied Loctite to all screws in the base and platform and fastened them to the specified torque. As I don’t have my own workshop, the whole build basically took place in my living room.

    Two obvious, but important things when designing a motion platform: it needs to be kinematically able to provide the desired range of motion, and it needs to be mechanically strong enough to do so. For the mechanical aspects, next to doing rough calculations on material stiffness, expected loads and motor torques, I used an online FEA tool (SimScale, https://www.simscale.com) to estimate the strength and expected deflection of individual custom parts like the crank arm and rods. For kinematics, I wrote a custom tool in Python (using Google’s JAX and numpy) that allowed me to find the range of motion for given platform parameters (like the common l1-l4 dimensions, crank arm length, etc…). As we’re talking about a 6 dimensional space here, making sense of the data is a problem in itself, and I ended up focusing on specific slices through the 6D volume that represent typical use case scenarios (like the sway/roll plane, which would be relevant for accelerations in the sway direction). This allowed me to compare different sets of parameters and chose the ones most suitable for my application. See below for an example of what the output of that tool looks like.

    Some stats:
    • 6 x 750W AC Servos
    • 6 x 50:1 Planetary Gearboxes
    • 6 x 80ST-M02430 (220V) AASD motor drivers
    • Edge-to-edge diameter of hexagonal base frame: 752mm
    • Footprint diameter (leg to leg): 1088mm
    • Crank arm length: 180mm
    • Rod length: 550mm
    • Weight of base and platform (without cockpit): ~180kg

    The final design (base and platform):
    20_cadmodel.jpg

    FEA was done using SimScale (deflection is exaggerated in this example):
    30_simscale.jpg

    Example output of my kinematic analysis tool. Each column of plots is for a specific platform heave position. Each plot runs over two specific dimensions of the 6D volume. Green indicates safe areas, yellow indicates ball head joint collisions, red indicates collisions with the base frame, white is unreachable.
    40_limitsim.jpg

    Using a similar tool, I computed the convex volume that fully contains the platform and cockpit, for any non-colliding configuration. This helped me figure out how much space the rig will occupy in my living room.
    50_motionrange.jpg

    The hexagonal base frame is taking on shape...
    60_baseframebuild.jpg

    Installing the motors. And yes, it has RGB, too!
    70_ithasrgb.jpg

    I did quite a few iterations on the crank arm. To make it strong enough but also reduce cost. The one in this picture is close to the final design - 3D-printed for test fitting. Note the Ringspann (https://www.ringspann.com/en) locking element used to attach the crank arm to the shaft of the gearbox.
    80_crankarm.jpg

    Triangular platform, fully assembled:
    90_triangularplatform.jpg

    I’ve been dry-running the controller using wooden sticks for the rods and platform assembly. Highly recommended, because there almost certainly will be collisions when configuring everything for the first time.
    100_woodensticks.jpg

    A custom rig was built to adjust the rods to their exact length:
    110_rodrig.jpg
    115_rods.jpg

    The fully assembled platform:
    120_fullplatform.jpg

    Closeup of the top ball head assembly. The screws through the ball heads are custom CNC-turned steel parts, and so are the high misalignment spacers.
    130_ballheads.jpg

    Closeup of the custom laser-cut Plexiglass cover:
    140_plexiglasscover.jpg
    • Like Like x 7
    • Winner Winner x 2
  3. Flying Pete

    Flying Pete Member

    Joined:
    Mar 28, 2021
    Messages:
    13
    Location:
    Switzerland
    Balance:
    120Coins
    Ratings:
    +60 / 0 / -0
    My Motion Simulator:
    6DOF
    Electrical:

    The AASD servo drivers feature sockets for D-Sub connectors. Most D-Sub plugs require a lot of vertical space, which increases the total height of the base. So I designed and 3D-printed custom connectors with a 90 degree bend (DB-25 and DA-15). While I was at it, I also shortened all motor cables and re-pinned the connectors. This was a lot of work, but reduced the overall length of cables to a minimum and made everything neater and more compact.

    I used shielding on all power cables. Pro tip: don’t waste time looking for shielded power cables online. It is much easier to just buy metal braid sleeving and put it over a regular 230V power cable. Signal cables were already shielded, but I added some ferrite cores for good measure.

    The servo drivers receive power from a power distribution box mounted to the bottom of the base. The box features two 230V AC C14 connectors, and each AC input contains a mains filter and a 10A fuse.

    The final platform (including the cockpit) features a total of 7 USB devices, connected to two USB hubs in series (one in the base, one in the cockpit). As the USB cable leading to the PC is relatively long, and the Motion4Sim controller draws quite some power, I found it important to use powered USB hubs (at least for the one in the base). I built a custom 3D-printed enclosure for the USB hub mounted to the bottom of the base, which allowed me to power it directly from the power box. Also, I installed a manual switch that interrupts the 5V line on the USB cable leading to the PC, so I can flip that switch instead of plugging and unplugging the USB cable. Which is important for the platform startup sequence (first power the servo drivers, controller, and USB devices. And only then connect USB to the PC).

    The rig as a whole has four outgoing cables:
    • USB
    • HDMI
    • 230V DC power
    • ButtKicker power/signal

    First test with the Motion4Sim Controller fully hooked up (just one servo at this point):
    150_motion4simwiring.jpg

    230V power distribution box:
    160_powerbox.jpg

    Custom 3D-printed 90 degree angled D-Sub plugs (red and orange):
    170_dsubplugs.jpg

    Re-wiring all the D-Sub cables was A LOT of work:
    180_dsubwires.jpg

    Custom 3D-printed box for the USB hub. A similar box was built for the 12V PSU for the 13” LCD monitor:
    190_usbhubbox.jpg
    • Like Like x 6
    • Winner Winner x 1
  4. Flying Pete

    Flying Pete Member

    Joined:
    Mar 28, 2021
    Messages:
    13
    Location:
    Switzerland
    Balance:
    120Coins
    Ratings:
    +60 / 0 / -0
    My Motion Simulator:
    6DOF
    Part 2: The Cockpit

    Similar to the base and platform, I relied heavily on item profiles for the cockpit (again, sized 40x40mm and 80x40mm). I did not fully design the cockpit ahead of time, but rather made some rough sketches, ordered the parts, and started experimenting. At design time, one may tend to over-engineer the cockpit to make it extra-stiff, which however also adds extra weight. I started with a very rugged design for the cockpit frame, but then ended up with a rather minimalistic construction that was still sufficiently rigid.

    I wanted the cockpit layout to match a Cessna 172. One challenge with VR is that one cannot see the physical controls, so ideally their location matches up with the virtual controls. I achieved this by exporting the model of the Cessna 172 cockpit from Microsoft Flight Simulator, importing it into my CAD program, and then placing the physical controls to match the model.

    I’m using the following flight controls:
    • Yoke: Honeycomb Alpha Flight Controls
    • Pedals: Ruddo PLUS pedals (VirtualFly)
    • Throttle: V3RNIO PLUS TPM (VirtualFly)
    • Flaps: custom Arduino-based, 3D-printed Cessna-style flaps lever

    Having a mouse and keyboard is still necessary in VR. A display is a bit of a luxury, but helps with setting everything up. I used:
    • 13.3" FullHD IPS Display
    • Logitech MX Ergo trackball mouse
    • Logitech G G413 keyboard

    It’s probably obvious why I opted for a trackball rather than a mouse. Also, one nice thing about the MX Ergo trackball is that it comes with a magnetically attachable base plate. I glued the metal base plate to the cockpit frame, and can now still remove the trackball at any time.

    The seat I used is actually a driver’s seat from a crashed Hyundai i30. No particular reason for that, I just went to the local junkyard and looked for a car seat that is in decent shape, not too heavy, and is manually adjustable. Mounting the seat rail to the cockpit required the construction of some special spacers with non-parallel surfaces, but otherwise was not very problematic. Additionally, a ButtKicker Gamer 2 transducer is mounted to the seat to get those sweet motor vibrations.

    Building up the cockpit frame:
    200_cockpitframe.jpg

    Cockpit details and flight controls. From left to right: Honeycomb Alpha. V3RNIO PLUS TPM. Custom Arduino-based flaps lever. Motion4Sim Remote Control box:
    210_flightcontrols.jpg

    Custom 3D-printed keyboard mount:
    220_keyboardmount.jpg

    The ButtKicker transducer is rigidly mounted to the internal structure of the seat:
    230_buttkicker.jpg
    • Like Like x 8
    • Winner Winner x 1
  5. Flying Pete

    Flying Pete Member

    Joined:
    Mar 28, 2021
    Messages:
    13
    Location:
    Switzerland
    Balance:
    120Coins
    Ratings:
    +60 / 0 / -0
    My Motion Simulator:
    6DOF
    Part 3: Control

    With the platform built and wired up, the next big topic is: how to drive it from Microsoft Flight Simulator (MSFS). The main steps are:
    1. Retrieve simulation data from MSFS (over SimConnect)
    2. Compute body forces (to be precise: fictitious acceleration and angular velocity) acting on a point below the pilot’s seat
    3. Filter/process the body forces and use them to compute the desired pose (rotation and translation) of the platform (aka motion cueing)
    4. From the pose, compute motor angles
    5. Send motor angles to the motion controller (Motion4Sim)
    There are quite a few applications out there that can handle these steps, such as FlyPT Mover and SimTools. However, I ended up using a custom solution for three reasons: first, the motion output of MSFS is incomplete, and I could not find any existing solution that computes the correct body forces. Second, I wanted a constant acceleration to result in the correct orientation (pitch and roll) of the platform. Third, I wanted collision detection, to prevent any parts of the platform from colliding or over-extending. On top of that, implementing all the steps myself was a great opportunity to learn and to make sure I fully understand every detail.

    Retrieving simulation variables from Microsoft Flight Simulator is relatively straightforward using SimConnect. One problem is that the most interesting variables are not available, namely the body forces, i.e. the fictitious accelerations one would measure using an accelerometer (e.g. on a smartphone) that is stationary in the cockpit. Fortunately, it is possible to compute the body forces from other sim variables. However, these accelerations are with respect to the plane’s origin, but what we are really interested in are the accelerations at a specific point in the cockpit, for example below the pilot’s seat (at the origin of the platform). Fortunately, SimConnect provides the “eye point position” variable, which can be used to estimate the position we are interested in. Without getting into the details of how to compute the accelerations in the cockpit, it basically comes down to a sum of four accelerations: the gravitational acceleration, the plane’s linear acceleration, centrifugal acceleration due to the angular velocity of the plane, and Euler acceleration due to the plane’s angular acceleration.

    For motion cueing, the acceleration vector as well as the angular velocity vector are filtered over time, using the usual combination of exponential moving average low- and high-pass filters (EMALP, EMAHP).

    To compute the platform pose, three individual transformation matrices are computed from these filtered vectors, and then combined into a single transformation (the target pose of the platform). Essentially: 1) the low-pass filtered acceleration vector is used to compute a transformation matrix that orients the platform such that the acceleration vector points downwards. For situations where the perceived acceleration is constant (on the ground, flying with constant velocity, in constant rate turns, etc…) this results in the perceived direction of the acceleration being correct (though the magnitude of the acceleration is always 1 G of course). 2) a transformation for a pure translation is computed from a high-, then low-pass filtered version of the acceleration vector. This transformation handles short bursts of acceleration and jerk, such as bumps on the runway, turbulence and impacts on landing. 3) a pure rotational transformation is computed from the high-, then low-pass filtered angular velocity vector. This gives the cues for angular motion.

    Additionally to the above, my implementation features collision detection and handling: after the motion cueing (step 3), I compute the full state of the platform (motor angles, rod positions and orientations). The state is then checked for mechanical collisions. After some analysis and testing, it turned out that for my setup, only two kinds of collisions need to be checked: collisions between each rod and the hexagonal base frame, and collisions within the ball head joints (i.e. when the joint angles exceed the maximum allowed value). If a collision is detected, it is handled as follows: the platform remains in the most recent collision-free configuration, and once the motion cueing outputs a new collision-free state, the platform smoothly transitions into that state. Also, whenever this happens, an audio sample is played back (which is not necessary, but useful for tuning motion cueing parameters).

    I consider collision detection and handling to be an essential feature, at least I would not have been able to drive the platform to its full range without it. I did have a few minor collisions while driving the motors manually during testing, and it can really mess things up. At one point I almost destroyed a ball head… So, very glad to have collision detection in place now.

    As mentioned, I’m using the Motion4Sim Servo Motion Controller (see https://www.xsimulator.net/community/threads/new-6dof-aasd15-servo-motion-controller.15356). It features two control modes: you can either drive it directly by sending it the motor angles, or you can send the platform pose values (rotation and translation, i.e. yaw/pitch/roll, heave/sway/surge) and it will then compute the corresponding motor angles in real-time. I ended up using the Motion4Sim controller in the first mode (sending motor angles), because I anyway had to compute them during the collision detection step.

    To tune-in the filter parameters and test the collision detection (and the software in general), I implemented various recording, playback, visualization and platform simulation tools in C++. The goal was to exercise the code in the same way it would be used during normal operation, to iterate quickly, and to be able to test as much as possible without involving the actual motion platform. See the screenshots below for more details.

    With all the motor angle computation and collision detection happening on the same machine that runs Microsoft Flight Simulator, you might wonder about performance impact. I have in fact considered using lookup tables or some compact representation of the 6-dimensional collision-free volume to make this as efficient as possible, but it turned out that directly doing the collision math is actually not that expensive. On my Intel Core i9-10900K, in a single thread, I can do about 800k “motion solves” (computations of motor angles and collision detections) per second, thanks to an efficient implementation in C++. Running the motion loop at 400 Hz, this results in 0.05% CPU usage on a single core. So it should not have any noticeable impact on the simulator.

    Finally, one important detail I want to point out: the AASD servo drivers need some tuning, too! As a minimum, the inertia ratio and stiffness class should be dialed in. Without proper tuning, the servos won’t run smoothly. In my case, the default values resulted in oscillations, even for simple, slow sinusoidal surge motions. To better understand the problem and dial in the optimal values, I used a mobile app that logs accelerometer measurements on a phone (https://apps.apple.com/ch/app/physics-toolbox-accelerometer/id1008160133?l=en). I placed the phone on the platform and recorded the accelerations, with and without a pilot, and used that to measure the amount of jitter and compare different settings. It can also be useful to calculate the theoretical inertia ratio from the platform mechanics, motor and gearbox specs, to get an idea for the ballpark figure.

    I recorded sim data from Microsoft Flight Simulator (via SimConnect) using a custom C++ tool and captured the screen at the same time. Then wrote the custom application shown below, which plays back the sim data and screen cap video in sync, allowing me to iterate quickly on the motion cueing algorithm.
    240_firstsim.jpg

    This version of the tool visualizes the resulting state of the platform at any point in time during playback. The barcode-"timeline" at the bottom indicates the collision state of the platform for every point in time of the recording. I used this to tune-in the motion cueing parameters for my specific style of flying, so I can use the full range of the platform without hitting a colliding state too frequently.
    250_platformsomwithcoll.jpg

    The application can also receive the live motor angles during a simulator session and visualize the resulting state of the platform. The image below shows the visualization and real platform side-by-side. This feature is useful for trying out more extreme motion cueing settings, or after the simulator gets a software update - to verify everything behaves as intended, without the risk of overstressing and damaging the platform.
    260_sidebyside.jpg

    Example output of accelerometer measurements as the platform moves forward and backwards. Having objective measurements like this (for the amount of platform vibration) is crucial for tuning in the servo parameters in a systematic way.
    270_accelerometer.jpg
    • Like Like x 5
    • Winner Winner x 1
    • Useful Useful x 1
  6. Flying Pete

    Flying Pete Member

    Joined:
    Mar 28, 2021
    Messages:
    13
    Location:
    Switzerland
    Balance:
    120Coins
    Ratings:
    +60 / 0 / -0
    My Motion Simulator:
    6DOF
    Part 4: VR

    Why do we need to talk about VR here? Two words: motion compensation. I’m using the HP Reverb G2 headset which estimates the position and orientation of the headset using cameras. This is always relative to the room you’re in. So by default, any motion of the platform would induce the same motion in the headset. E.g. if the platform rolls left, your head and the headset also roll left. This gets picked by the headset and your head ends up outside of the virtual airplane. But we want all headset motion to be relative to the cockpit, not the room, and motion compensation is what solves this problem.

    The issue is that Microsoft Flight Simulator runs best with the Reverb G2 when using the Windows Mixed Reality (WMR) OpenXR runtime (as opposed to other runtimes like Steam VR’s). But WMR does not provide support for motion compensation. This is one of the things I didn’t really know how to solve initially, and which could have been a dead-end for the whole project. From my experience, at least for flight simming, motion compensation is really a must-have. If you accelerate the plane on takeoff, you don’t want to feel like your seat is starting to tilt back by 20 degrees relative to the rest of the virtual cockpit. You want your head to stay where it is in the virtual cockpit, and just feel the acceleration pushing you back into the seat.

    So, how did I get around the lack of motion compensation support in WMR’s OpenXR runtime? I basically implemented my own OpenXR runtime that acts as a man-in-the-middle: when MSFS asks my runtime about the location of the headset, it retrieves the headset location from the “real” WMR runtime, changes its location and orientation to compensate for the platform motion, and returns that back to MSFS. There’s more to say about this that I won’t cover here - just two details I want to point out: first, we need to know where the headset is located in relation to the base of the platform. This requires a calibration step. I 3D-printed a mounting frame for the Reverb G2 (HP are so kind to provide 3D CAD files for their headset, which makes creating accessories a lot easier!). The location of that frame (relative to the platform) is exactly known, so by placing the headset in the mounting frame and triggering the calibration, we know the location of the headset relative to the platform and are all set. Second, you might wonder how my OpenXR runtime knows the state of the platform. The answer is: it actually controls the platform. Basically, everything runs inside my OpenXR runtime (and hence runs in the MSFS process itself): the retrieval of the sim variables over SimConnect, the motion smoothing, motion cueing, computation of the platform pose, computation of motor angles and collision detection, sending of the motor angles to the controller, and VR motion compensation. It also means that everything “just works”. There’s no need to start up any other applications on the side. And it also allows for a very convenient flow for the calibration process, as I can combine it with MSFS’s internal headset calibration: in MSFS I enable VR mode, place the headset in the calibration frame, hit the spacebar, and I’m good to go. The headset is now perfectly registered to the cockpit (and to the flight controls) and motion compensation can do its job. Couldn’t be any more convenient really.

    A note on controllers, which Microsoft Flight Simulator supports since Sim Update 7 (released November ‘21): those need to be motion-compensated, too. So I had to make a few adjustments to my code to properly support them.

    Custom 3D-printed calibration mount for the HP Reverb G2:
    280_hmdmount.jpg

    Overview of the motion compensation solution. Top is how things normally work, bottom shows my solution with a custom OpenXR runtime.
    290_wmrdiagram.jpg
    • Like Like x 3
    • Winner Winner x 2
  7. MarkusB

    MarkusB Well-Known Member Gold Contributor

    Joined:
    Jun 30, 2015
    Messages:
    552
    Location:
    Germany
    Balance:
    4,213Coins
    Ratings:
    +596 / 2 / -0
    My Motion Simulator:
    2DOF, 3DOF, DC motor, Arduino, Motion platform
    Congratulations! This is not only an incredibly beautiful and professional-looking rig, but also your efforts and ideas for building (and simulating) it are really impressive.

    Now the only thing missing is a video.
    • Agree Agree x 4
  8. pmvcda

    pmvcda aka FlyPT

    Joined:
    Nov 3, 2010
    Messages:
    2,093
    Location:
    Portugal
    Balance:
    14,898Coins
    Ratings:
    +2,499 / 17 / -0
    My Motion Simulator:
    6DOF
    Great work!
    I'm reviewing myself in the path you made.

    Did not notice the “eye point position” variable in SimConnect.
    I have the correction in Mover, but I think that only Condor2 is filling automatically the pilot position in the source module.
    Will add it for the next release.

    I'm more in the cars right now.
    Would love to know your impressions on what is your preferences for motion cueing and how are you handling the rollovers.
    Not for saying its good or bad, it all depends on the user and what he expects.
    Just to get an idea of the diversity of opinions.
    I can tell you for example, that in cars I have people using different directions on the accelerations.
    I find it strange, but that's what they like.
    Some even use the opposite direction in VR, compared to non VR use.
    (usually in the sway direction)

    And one more vote for the video.
  9. Flying Pete

    Flying Pete Member

    Joined:
    Mar 28, 2021
    Messages:
    13
    Location:
    Switzerland
    Balance:
    120Coins
    Ratings:
    +60 / 0 / -0
    My Motion Simulator:
    6DOF
    Alright, I've uploaded a couple of videos. Not the greatest production value, but better than nothing I guess.

    Testing a single motor:


    Just the platform, driving it using the Motion4Sim software:


    Platform simulation on pre-recorded flight in MSFS:


    A flying session in VR:
    • Like Like x 5
    • Winner Winner x 2
  10. Flying Pete

    Flying Pete Member

    Joined:
    Mar 28, 2021
    Messages:
    13
    Location:
    Switzerland
    Balance:
    120Coins
    Ratings:
    +60 / 0 / -0
    My Motion Simulator:
    6DOF
    Thanks pmvcda!

    Well, it's an interesting problem - trying to achieve an experience that is as close as possible to the real thing. I think what makes it difficult is that it is impossible to get right, so tradeoffs need to be made, and different people might perceive these tradeoffs differently. For my setup, I find the least realistic part is taxiing on the ground, so huge respect to people doing driving sims! I think a big part of the problem are transitions. It's clear that in a right-turn, one wants to feel a constant centrifugal acceleration to the left, so during the turn the platform remains rolled to the left. The difficult part is the transition from going straight to being in that right turn - the platform basically has to roll to the left without the user noticing it.

    I do think screens vs. VR makes a huge difference. Especially in my setup, where the screen is tiny and thus the motion of the platform relative to the room is very obvious. E.g. while testing things and flying with a screen only, I often had pilot-induced oscillations (PIO), where in case of a pitch motion, the user would overcompensate (by e.g. pushing the yoke), so the pitch angle of the platform would start to oscillate, resulting in stronger and stronger up/down pitching. This doesn't happen in VR for me. So I suspect the effect has to do with the user being aware of the motion of the platform (because they can see it), so they act differently than if they would only "feel" the motion (such as in VR). Because of that it would make sense to me if different setups require different motion cueing methods. But this also probably means that a true-to-life experience can only be achieved if the user has no visual reference for the motion of the platform (i.e. to use VR, or very large screens in a dark room).

    If by rollover you mean going upside down: as described above, I have three transformations. Two of them (momentary acceleration and rotational speed) do not depend on the absolute acceleration, so there's no problem there. The third one (static acceleration) I basically handle by correcting the acceleration vector as follows:

    Code:
    accelStatic.y = -max(abs(accelStatic.y), minAccel))
    I use minAccel = 0.8G. So what this does is it makes the acceleration vector always point down (negative y), and makes sure it always has a magnitude of at least 0.8G. For GA flying you don't do loopings and such, but when pushing down on the yoke it can happen that you become weightless or the acceleration vector even points upwards (think of a parabolic zero-G flight). The above correction works well for this case.

    Btw: thanks a lot for making FlyPT Mover, love the app, and it was incredibly useful on my journey to understand how any of this works. Which is why I also adopted the Mover dimensioning and numbering conventions. :)
  11. cfischer

    cfischer Active Member Gold Contributor

    Joined:
    Sep 7, 2015
    Messages:
    371
    Location:
    Colorado
    Balance:
    2,681Coins
    Ratings:
    +259 / 1 / -0
    Amazing. Super clean mechanical build. A pleasure to look at and very capable. But the software efforts are even more impressive. Interesting that you've built your motion cuing into openxr. Does this mean your efforts are limited to MSFS2020? Are you limited to the Reverb G2? Sounds like you've flown with screens so I assume you're not limited to vr only.
  12. Flying Pete

    Flying Pete Member

    Joined:
    Mar 28, 2021
    Messages:
    13
    Location:
    Switzerland
    Balance:
    120Coins
    Ratings:
    +60 / 0 / -0
    My Motion Simulator:
    6DOF
    Thanks. Nothing specific to the Reverb G2 here, that approach should work for any headset supported by MSFS (ie any headset with OpenXR support). I’m making some assumptions on the kind of OpenXR calls made by the Sim, in particular for the calibration, so this is somewhat brittle and may not work for other apps (or future versions of MSFS for that matter). I think it should be possible to implement it in a more robust way though. Yes I can also run it without VR (without motion compensation), as a stand-alone app that retrieves sim data using SimConnect and sends motor angles to the Motion4Sim controller.
    • Like Like x 3
  13. Gadget999

    Gadget999 Well-Known Member

    Joined:
    Dec 27, 2015
    Messages:
    1,935
    Location:
    London
    Balance:
    11,838Coins
    Ratings:
    +472 / 9 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino, 6DOF
    That is a really nice professional build and a very good presentation of the facts too.

    I looks like it could be adapted into a driving sim quite easily.

    VR gives you the advantage that you don't need to build a realistic cockpit and can easily swap between plane layouts.

    Do you have a pilots license ?
  14. tu xiao mi

    tu xiao mi Member Gold Contributor

    Joined:
    Aug 10, 2021
    Messages:
    71
    Balance:
    486Coins
    Ratings:
    +5 / 0 / -0
    My Motion Simulator:
    Arduino, 6DOF
    amazing beautiful, do you use hall to stop it?
  15. tu xiao mi

    tu xiao mi Member Gold Contributor

    Joined:
    Aug 10, 2021
    Messages:
    71
    Balance:
    486Coins
    Ratings:
    +5 / 0 / -0
    My Motion Simulator:
    Arduino, 6DOF
    could you share your CAD project?
    • Like Like x 1
  16. Captain Jack

    Captain Jack Member

    Joined:
    Nov 20, 2021
    Messages:
    37
    Balance:
    - 26Coins
    Ratings:
    +41 / 1 / -0
    My Motion Simulator:
    2DOF, Arduino
    This must be one of the best sims I've seen so far. I'm impressed with how smooth the motion is in the videos
  17. smitty

    smitty Active Member

    Joined:
    Aug 24, 2021
    Messages:
    130
    Balance:
    804Coins
    Ratings:
    +180 / 2 / -0
    My Motion Simulator:
    6DOF
    Looks awesome! Can you go into more detail about tuning the AASD's? I assume it's like PID tuning, but what parameters are you adjusting? What are you looking for in the measured accelerations?
    • Agree Agree x 1
  18. Flying Pete

    Flying Pete Member

    Joined:
    Mar 28, 2021
    Messages:
    13
    Location:
    Switzerland
    Balance:
    120Coins
    Ratings:
    +60 / 0 / -0
    My Motion Simulator:
    6DOF
    Thanks all.

    Yes driving sim would theoretically be possible, but I don’t have the pedals / steering wheel for that.

    For VR you still want to have a cockpit layout that matches the one in the sim. Yes it doesn’t have to be pretty or super realistic, just needs the buttons and knobs to be in the right place :)
    I’m currently looking into building a cockpit that matches the Piper Warrior II, and then I’ll also add hand tracking+visualization (got a working prototype) to make it easier to find the controls.

    No I don’t have a private pilots license (yet) ;)

    I’m just using the torque limit to home it (no hall sensor). The crank arm hits a 3D printed part that is strong enough to trigger the torque limit, but would give way if something goes wrong and the arm moves further than the stop (hasn’t happened yet, fortunately).
  19. Flying Pete

    Flying Pete Member

    Joined:
    Mar 28, 2021
    Messages:
    13
    Location:
    Switzerland
    Balance:
    120Coins
    Ratings:
    +60 / 0 / -0
    My Motion Simulator:
    6DOF
    On AASD tuning: I first made sure that automatic gain adjustment is on (Pn258=1). This was in fact already the case for my servos, contradicting the defaults mentioned in the manual (so I would recommend not relying on the defaults but instead check all relevant driver parameters). With automatic gain adjustment, you don’t have to tune all the individual PID parameters (of which there are many) but instead just select a stiffness class. I used class 4 (Pn259=4) and left it at that (class 3 and 5 did not improve things after tuning the inertia ratio, see below).

    Instead I tuned the inertia ratio (Pn257). Default is 1.0 and I ended up with 4.0. To find this I drove the platform position using

    z = sin(t * 2 * pi * f) * a

    with t = time in seconds, a = 0.15m and f = 0.1…0.6 Hz. While recording the X/Y/Z accelerations on the platform using this iPhone app: https://apps.apple.com/ch/app/physics-toolbox-accelerometer/id1008160133?l=en. See above for an example plot. Increasing the inertia ratio tended to reduced the vibrations, which was not easy to judge visually from the behavior of the platform, but was clearly visible in the plots (reduced amplitude in the acceleration). At some point (inertia ratio > 6) the servos noticeably started “whirring”, even when at rest. I assume that’s when the controller response was too fast, so I dialed it back from there.

    I’m sure there are more principled ways to fine-tune this, but I was able to improve the controller response over the default settings and am happy with how it behaves now.
    • Useful Useful x 1
  20. cfischer

    cfischer Active Member Gold Contributor

    Joined:
    Sep 7, 2015
    Messages:
    371
    Location:
    Colorado
    Balance:
    2,681Coins
    Ratings:
    +259 / 1 / -0
    Interesting. My AASD manual doesnt show pn values above 219. Can you share this manual you're referring to?