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

Showroom Portable budget G-Seat plus office chair spin. Perfect for beginners. No power tools needed!

Discussion in 'DIY Motion Simulator Projects' started by Jumping Coin, Sep 28, 2020.

  1. Jumping Coin

    Jumping Coin Member Gold Contributor

    Joined:
    Aug 7, 2020
    Messages:
    93
    Balance:
    470Coins
    Ratings:
    +54 / 0 / -0
    Just finished up my first build ever. I constructed a g-seat that can easily be removed from my office chair and stored in a closet. I also added a feature to spin the office chair about 10 degrees in each direction to help accentuate the g-seat. My craftmanship is pretty lacking, especially compared to the many masterpieces featured on this forum, but amazingly enough the seat does its job and has offered a whole new dimension to the sim-racing experience!

    I know that there are several excellent pneumatic g-seat write-ups already, notably
    @volker metzger 's g-seat build (https://www.xsimulator.net/community/threads/diy-full-pneumatic-g-seat-ideal-for-beginners.13089/) , and @Banfy ’s build (https://www.xsimulator.net/community/threads/a-foldable-diy-sim-rig-with-g-seat.14948/). Finding @volker metzger's build was a eureka moment, and @Banfy's build offered truly excellent inspiration. I hope to contribute to these builds by adding a new spin (pun intended) by enhancing the g-seat with a small amount of spin from the office chair. In addition, I wanted to create a g-seat that was extremely portable and easily removable, especially for those who race by night on their office chairs. In addition, I hope to add enough detail that a beginner with the simplest of tools could take advantage of. Being a DIY-phobe myself, I chose to use simple parts, and I had no real power tools beyond a simple drill. (I used the drill only to make a few holes in a small cutting board for spinning the office chair, but even that could have been done by hand if necessary.) Because of a lack of DIY skills, I didn’t weld, solder, or even saw. I did, however, overly rely on zip-ties, which I still need to clean up.

    I’m new to the sim-racing scene, and I don’t have much room to devote to a full-sized rig. Thus, I wanted a portable rig that can be easily stored away when not in use. I also really love my office chair, and I didn’t want a separate chair for racing. In addition, I wanted to capitalize on the spinning nature of it to slightly simulate sway and add some nuance for corning in the g-seat. I was surprised that I couldn’t find any examples of people spinning their office chairs. Of course I didn’t want to spin too far away from the pedals, but I thought a good 10 degree spin in either direction would be just enough.

    I began sim-racing with a T300 wheel, cheap off-brand wheel stand, and a Realteus Force Feel haptic feedback pad. The games were fun, but I missed not having all of the g-force cues from sliding into a turn IRL. Poking around the internet, I came across Bergison’s Motion Integrated G-Seat, and thought wow, I can’t wait for that to come to market! Then I found the GS-5 and Geko seats, but they were $2000 to $3000, much beyond anything my wife would let me spend on a “video game”. That’s when I came across this site, and the awesome projects on display here, and I knew I had to jump in!

    My budget was about $500, and I stayed under it, although I could have trimmed it a bit more by buying products from overseas instead of Amazon. However, with Covid going around, I didn’t want to take any chances that deliveries would be delayed.

    The first step was to find a container for the g-seat air wedge bladders, hinges, Arduino, etc. to which I could easily attach components. I figured a 13x13x11 plastic milk crate would do the job nicely.

    upload_2020-9-28_1-8-2.png

    I searched high and low for the types of hinges that have been used by some of the other g-seats (I literally checked every hinge on hinge outlet website), but apparently they aren’t sold in the U.S. and I couldn’t get them shipped here. In the end, I decided to use 10x10 inch triangular hinges.

    upload_2020-9-28_1-41-51.png

    I used four 60 kg servos and attached them to the hinges with zip-ties.

    upload_2020-9-28_1-42-17.png

    At first I tried using 100 lbs rated steel wire between the servo arm and the hinge, but it was a bit unwieldy for me to set it to the right length. Eventually I gave zip ties a try, and even though they might be a bit underrated in KGF, they seem to be holding up well enough without any signs of wear. However, should they ever snap, I used 3 inch zinc-plated corner braces as a protective stopping point to prevent any of the internals from getting smashed.

    upload_2020-9-27_23-16-4.png



    upload_2020-9-27_21-47-41.png

    For power supply, I connect each servo to its own AC-DC adapter, which are adjustable from 5 to 15 volts. I chose to play it safe and use 6 volts for each servo even though the servos are rated to work best at 7.4 volts. They seem to work just fine with 6 volts. I should also mention that I picked adapters that were small enough that I could easily fit all five into a single power strip. I used a small bread board to connect the negative wire from each AC-DC adapter to the negative servo wire and the Arduino GND. In case it helps, in the below picture, the white wires are the Arduino GND, the brown wires are the negative from the servo, and the black wire is the negative from the power supply. An easy mistake is to forget that the negative charge needs to run back to the GND on the Arduino, so this is a reminder to not forget that step. There may be better ways to do this, but this worked for me.

    upload_2020-9-27_21-52-4.png

    upload_2020-9-28_1-0-20.png

    The Arduino board and wires sit in the middle. I decided it was best to elevate the board and wires, just in case there was ever a spill on the floor, so I used a to-go food container that I found laying around.

    upload_2020-9-28_0-52-23.png

    As for the bladders, I used four on the seat ala GS-5 style; two bladders on the bottom of the seat to represent acceleration and sway, and two bladders on the back of the seat to represent deceleration and sway. I wanted the bladders to be attached via velcro so that I could continuously fiddle with finding the best location for them, and I didn't want to attach them directly to the Realteus pad in case I ever wanted to switch it out. I could have used a seat cushion pad, but since it would be placed under the Realteus pad, I didn't want a cushion under a cushion. Instead, I decided to use a reusable plastic bag as a base, and attached two pool noodles for side support via duct table. Cheap, yes, but it does the job.

    upload_2020-9-27_22-49-48.png

    upload_2020-9-27_21-57-38.png



    I added velcro strips to the seat and attached four 11x4 inch air wedge bladders.

    upload_2020-9-28_0-30-27.png

    The whole thing fits nicely under the Realteus pad, and while it isn't pretty, it isn’t quite the eyesore that I expected it to be.

    upload_2020-9-28_1-46-52.png

    Inside the milk crate, I used four 6x6 inch air wedge bladders, which connected to 5mm (3/16 Inch) inner diameter high performance silicone vacuum hose line. All total I used 15 feet of hose, but if I were to do it again, I'd use 20 feet since it's a little tight when removing from the office chair. These hoses are then connected to 5mm (3/16 inch) tees, and then connected to the other air bladder and pump. As @volker metzger recommended, I used the squeeze pumps with push button release valves rather than the turn value release.

    upload_2020-9-28_1-10-28.png

    I added three 3x7 inch galvanized plates and attached them to the milk crate via two 4 inch zinc-plated corner braces. Then I added rubber caster stoppers where the office chair would rest upon. The milk crate is fine without the caster wheel stoppers, but having them means that the office chair doesn’t roll away from the crate. The caster wheel stoppers also holds the office chair to connect it to the servo for spinning.

    With the g-seat complete, I could focus on spinning the chair. While this part might be simple for many here, I racked my brain for a couple of weeks trying to figure how to best accomplish it and allow it to be removable. I finally settled on a hacky version of a slider crank. I’m certain that this can be greatly improved, but it seems to do the job for now. Basically, I took an old cutting board, screwed it to an 8- inch zinc-plated corner brace, and zip-tied it to bottom of the seat. Then, I zip-tied a servo to the middle 3x7 inch plate and held it in place using two 2-inch zinc plated corner braces. I zip-tied a camber joint for an RC car to the servo arm and wrapped a velcro strip around it. Later, I may also switch out the camber joint for perhaps a pvc pipe or some other material if I decide to increase the spin by a few more degrees.

    upload_2020-9-28_0-46-39.png

    upload_2020-9-28_1-2-34.png

    Here's a video of the chair spin (keep in mind that the chair moves a bit less with someone sitting on it.):

    Here's my completed rig. (Apologies for the mess in the background. I put this together in the pantry, which is blocked off so that my toddlers can’t get to it.)


    upload_2020-9-28_1-24-3.png

    And here's my rig when it's time to call it a night (I added an extra milk crate for storage):
    upload_2020-9-28_1-25-19.png

    All told, it’s not the most glamorous device, and I still need to clean it up a bit, but I pretty much achieved what I set out for. In case it helps, I’m 160 lbs and 5’8’’. The air wedge bladders for the g-seat push me around without any strain on the servos and the feedback seems immediate. As for the office chair spin, if I try really hard I might be able to slightly stall the servo, but under normal brake/accelerator pressure, it works fine. Also, I lowered my chair all the way down and leaned/locked it all the way back. The seating position is definitely not F1 style, but it does come pretty close to feeling like my VW GTI daily driver.


    Here's the code that I used:
    (code updated 2020-11-17)
    Code:
    /************************************************/
    // Title:    Pneumatic G-Seat using 4 servos (L, R, T, B); Office Chair Spin using 1 servo (S)
    // Function: For use with Simtools software, apply sway, surge, heave, traction loss
    // Code adapted from: https://www.xsimulator.net/community/threads/low-cost-2dof-3dof-6dof-motion-simulator-dof-reality.8570/page-43#post-166682,
    // which had been adapted from https://www.xsimulator.net/community/threads/rc-model-for-motion-simulation.4600/
    //
    /************************************************/
    /*
    Values for interface:
      Interface Type : Serial
      Comport : is at every individual
      BitsPerSec : 9600
      Data Bits : 8
      Parity : None
      Stop Bits : 1
      Bit Range : 8
      Output Type : Decimal
      Interface Output : L<Axis1a>~R<Axis2a>~T<Axis3a>~B<Axis4a>~S<Axis5a>~
      Output Rate : 10ms
    Pins:
      4 = Left   (L)
      5 = Right  (R)
      6 = Top    (T)
      7 = Bottom (B)
      8 = Spin   (S)
    */
    #include <Servo.h>
    /*******************************************************************************************
    Users may need to modify the below section. See variables:
        kActuatorCount
        kPins
        kActuatorName
        kPosAndNeg[kActuatorCount]
        kActuatorScale
    Please ensure that kActuatorCount matches the number of elements in the other variables in this section.
    *******************************************************************************************/
    // number of servos
    const int kActuatorCount = 5;
    // Initials for servos, must match Interface Output specified in GUI
    const char kActuatorName[kActuatorCount] = { 'L', //Left
                                                 'R', //Right
                                                 'T', //Top
                                                 'B', //Bottom
                                                 'S'  //Spin
                                               };
    //Pin locations on Arduino board
    const int kPins[kActuatorCount] = {4, 5, 6, 7, 8};
    /*kPosAndNeg allows you to specify whether a given servo will respond to only one side of a DOF, i.e. -100 to 0 or 0 to 100 (kPosAndNeg[i] = 0); or full range of a DOF, i.e -100 to 100 (kPosAndNeg[i] = 1).
     For example, if you only want the actuator to operate only on acceleration and not the braking for surge, then set kPosAndNeg[i] = 0
     If you want the actuator to activate across the whole range of acceleration and braking for surge, set kPosAndNeg[i] = 1
    */
    const int kPosAndNeg[kActuatorCount] = {0, 0, 0, 1, 1};
    //safe position aka starting position.  For G-seat, I want servos as open as possible for safety reasons.
    int actuatorPosition[kActuatorCount]={0, 0, 0, 0, 55}; 
    //Set range of position (i.e. servo range from 0 to 180)
    const int kActuatorScale[kActuatorCount][2] = { 
                                                      {0, 180}, 
                                                      {0, 180}, 
                                                      {0, 180}, 
                                                      {0, 180}, 
                                                      {0, 110} //limit spin scale to ensure uniformity for left and right based on position relative to seat
                                                  };     
    /********************************************************************************************
    End of modification section.  No need to modify anything below for g-seat or servo-based simulators
    ********************************************************************************************/
    Servo actuatorSet[kActuatorCount];                  // our array of Actuators
    const char kEOL = '~';                              // End of Line - the delimiter for our acutator values 
    const int kMaxCharCount = 3;                        // some insurance...
    // set up some states for our state machine
    // psReadActuator = next character from serial port tells us the Actuator
    // psReadValue = next 3 characters from serial port tells us the value
    enum TPortState 
    { 
      psReadActuator, 
      psReadValue 
    };   
    int currentActuator;                                // keep track of the current Actuator being read in from serial port
    int valueCharCount = 0;                             // how many value characters have we read (must be less than kMaxCharCount!!
    TPortState currentState = psReadActuator;
    void setup()
    {
        // attach the Actuators to the pins
        for (int i = 0; i < kActuatorCount; i++) 
            actuatorSet[i].attach(kPins[i]);
        // initialise actuator position
        for (int i = 0; i < kActuatorCount; i++) 
            updateActuator(i);
         
        Serial.begin(9600); // opens serial port at a baud rate of 9600
    }
    /*************************************************/
    void loop()
    {
    }
    /**************************************************/
    // write the current Actuator position to the passed in Actuator 
    void updateActuator(int thisActuator) {
        int safePos;
        safePos=actuatorPosition[thisActuator];
        actuatorSet[thisActuator].write(safePos);
    }
    // this code only runs when we have serial data available. ie (Serial.available() > 0).
    void serialEvent() {
        char tmpChar;
        int tmpValue;
     
        while (Serial.available()) {
            // if we're waiting for a Actuator name, grab it here
            if (currentState == psReadActuator) {
                tmpChar = Serial.read();
                // look for our actuator in the array of actuator names we set up 
                #ifdef DEBUG           
                  Serial.print("read in ");           
                  Serial.println(tmpChar);           
                #endif
                for (int i = 0; i < kActuatorCount; i++) {
                    if (tmpChar == kActuatorName[i]) {
                        #ifdef DEBUG           
                            Serial.print("which is actuator ");           
                            Serial.println(i);           
                        #endif
                        currentActuator = i;                        // remember which actuator we found
                        currentState = psReadValue;                 // start looking for the Actuator position 
                        actuatorPosition[currentActuator] = 0;      // initialise the new position
                        valueCharCount = 0;                         // initialise number of value chars read in 
                        break;
                    }
                }
            }
           
            // if we're ready to read in the current Actuator's position data
            if (currentState == psReadValue) {
                while ((valueCharCount < kMaxCharCount) && Serial.available()) {
                    tmpValue = Serial.read();
                    if (tmpValue != kEOL) {
                        tmpValue = tmpValue - 48;
                        if ((tmpValue < 0) || (tmpValue > 9)) tmpValue = 0;
                        actuatorPosition[currentActuator] = actuatorPosition[currentActuator] * 10 + tmpValue;
                        valueCharCount++;
                    }
                    else break;
                }
               
                // if we've read the value delimiter, update the Actuator and start looking for the next Actuator name
                if (tmpValue == kEOL || valueCharCount == kMaxCharCount) {
     
                    #ifdef DEBUG           
                        Serial.print("read in ");           
                        Serial.println(actuatorPosition[currentActuator]);           
                    #endif
     
                    //if kPosAndNeg[i] == 0, then apply servo to only one side of a DOF (i.e -100 to 0 or 0 to 100)
                    if (kPosAndNeg[currentActuator] == 0)
                    {
                        //No -ve on G-seat : 90 = middle
                        if (actuatorPosition[currentActuator]<127)
                        {
                            actuatorPosition[currentActuator]=127;
                        }
                        // scale the new position
                        // Range is now 0 - 255
                        // Maps between min and max
                        actuatorPosition[currentActuator] = map(actuatorPosition[currentActuator], 127, 255, kActuatorScale[currentActuator][0], kActuatorScale[currentActuator][1]);
                    }
                    //else kPosAndNeg[i] == 1, so apply servo to full range of DOF (i.e. -100 to 100).
                    else 
                    {
                        actuatorPosition[currentActuator] = map(actuatorPosition[currentActuator], 0, 255, kActuatorScale[currentActuator][0], kActuatorScale[currentActuator][1]);
                    }
                   
                    #ifdef DEBUG           
                        Serial.print("scaled to ");           
                        Serial.println(actuatorPosition[currentActuator]);           
                    #endif
     
                    updateActuator(currentActuator);
                    currentState = psReadActuator;
                }
            }
        }
    }
    
    Just wanted to say thanks again to the community and to @volker metzger and @Banfy in particular for giving me the confidence that I could pull off something like this. Volker’s build caught my eye especially because it was labeled “ideal for beginners”, so I hope my thread similarly helps any office chair sim-racers looking to add some fun.

    Here is my complete parts list:

    Attached Files:

    • Like Like x 4
    • Creative Creative x 2
    • Friendly Friendly x 1
    Last edited: Nov 18, 2020
  2. Banfy

    Banfy FR/AU

    Joined:
    Jun 11, 2020
    Messages:
    131
    Location:
    Australia
    Balance:
    299Coins
    Ratings:
    +55 / 1 / -0
    My Motion Simulator:
    DC motor, Arduino
    Fantastic !
    Congrats on your build and totally in the spirit of mine, cheap, efficient, versatile
    cheers
  3. RacingMat

    RacingMat Well-Known Member Gold Contributor

    Joined:
    Feb 22, 2013
    Messages:
    2,234
    Location:
    Marseille - FRANCE
    Balance:
    20,890Coins
    Ratings:
    +2,083 / 21 / -2
    My Motion Simulator:
    2DOF, DC motor, Arduino
  4. Banfy

    Banfy FR/AU

    Joined:
    Jun 11, 2020
    Messages:
    131
    Location:
    Australia
    Balance:
    299Coins
    Ratings:
    +55 / 1 / -0
    My Motion Simulator:
    DC motor, Arduino
    So after a bit of use, how does the chair spin feel?
  5. Jumping Coin

    Jumping Coin Member Gold Contributor

    Joined:
    Aug 7, 2020
    Messages:
    93
    Balance:
    470Coins
    Ratings:
    +54 / 0 / -0
    Hi Banfy!

    I'm really liking it so far. I actually changed it around a bit after watching how real sims employ traction control. Now I have the servo off-centered, and I moved the R/C cam-rod to the end of the servo arm, and then bolted it into the corner brace that is attached to the chair, rather than velcroing it around the brace. Then I just attach a nut to the bolt and it's ready to go. Previously there was a little too much slack in it causing a lack of precision. The current version is a bit more precise and spins the chair about 15 degrees in each direction. It's not perfect of course. Since the rotation of the chair is so tight, it feels more like a narrow go-kart than a full-sized car, but it scratches my itch for sliding sideways. To be honest, it probably hurts my lap times a bit because of the extra twisting, but my driving is pretty weak anyway. More importantly, it adds to the immersion, and it's fun to spin-out and do donuts. Recently, after a spirited ride, I noticed a little bit of metal dust accumulating where the bolt meets the corner brace, most likely from the friction between the grooves of the bolt and the corner brace. I've since covered the bolt with some electric tape, so hopefully that should fix it. I'm hoping to do a proper write-up for version 1.2 very soon.

    I also purchased some parts for version 1.3, lol. (I think I'm having even more fun trying to figure out how to add more immersion on the cheap than actually driving!)

    Gonna see if I can make a cheap surge device by adding a servo to the wheelstand to pull my chair about 2 inches forward. Without locking the caster wheels, the chair naturally slides backwards when you hit the pedals, so between the chair sliding back and then being pulled forward by the servo, I'm hoping to get a few inches of back and forth movement. Not sure how it'll turn out, but I'll keep you posted.
    • Like Like x 1
  6. Jumping Coin

    Jumping Coin Member Gold Contributor

    Joined:
    Aug 7, 2020
    Messages:
    93
    Balance:
    470Coins
    Ratings:
    +54 / 0 / -0
  7. Banfy

    Banfy FR/AU

    Joined:
    Jun 11, 2020
    Messages:
    131
    Location:
    Australia
    Balance:
    299Coins
    Ratings:
    +55 / 1 / -0
    My Motion Simulator:
    DC motor, Arduino
    great , i will follow the improvements
    Have you thought about a gas exhaust and burnt tyre rubber smell simulator ? ;-)
  8. Jumping Coin

    Jumping Coin Member Gold Contributor

    Joined:
    Aug 7, 2020
    Messages:
    93
    Balance:
    470Coins
    Ratings:
    +54 / 0 / -0
    :grin LOL! Now that would be true immersion! Can't say I've seen anyone pull that off yet...
  9. Jumping Coin

    Jumping Coin Member Gold Contributor

    Joined:
    Aug 7, 2020
    Messages:
    93
    Balance:
    470Coins
    Ratings:
    +54 / 0 / -0
    Since I started, I might as well post the rest of version 1.2 build before I forget. So far the g-seat has been a blast, but after using it for a bit, I decided to add some upgrades.

    Originally I put the bladders under the Realteus pad, but that meant that the Realteus transducers would dig into my back, so I decided to attach the bladders directly to the top of Realteus pad with velcro. I also added a second air wedge bladder to each hinge, so now each servo activates two air wedges. Of course both air wedges share the same DOF, but this means that I can expand the placement of them.

    With eight air wedges at my disposal, I decided to dedicate each actuator to either sway or surge, rather than splitting it 50%-50% as I had done previously. I've also moved them around a bit. Here's the new placement:
    • One 11x5 inch bladder on the left side of the seat by the ribs (under a shortened pool noodle) and one 7x5 inch on the bottom of the side under my left thigh, which inflate for left turns
    • One 11x5 inch bladder on the right side of the seat by the ribs (under a shortened pool noodle) and one 7x5 inch on the bottom of the side under my right thigh, which inflate for right turns
    • Two 7x5 inch bladders on the back of the seat at the shoulders, which inflate on acceleration
    • One 11x5 inch bladder on the bottom of the seat and one 11x5 inch bladder on the pedal base under my heels to deflate for acceleration and inflate for braking
    upload_2020-11-18_0-25-2.png

    upload_2020-11-18_0-27-7.png

    upload_2020-11-18_0-42-59.png

    While the servos are all set to 100% sway or surge, I also have each servo set to an additional heave at 20% to 30%. Since that brings each actuator above 100%, there might be some clipping, but since heave is a small minority and just there to add a little randomness to simulate road surface, any clipping is barely noticed. I didn't realize how having heave adds to the realism; without it, the road just felt way too smooth. Placing a bladder near the pedals seemed like it would be a bad idea at first since I thought it might interfere with pedal use, but surprisingly it works really well as long as it was under my heels and not the arches of the feet. In fact, sometimes when I finish racing for the night, I get the same sensation as when I step off of a boat after a long ride; it takes a minute to get my land legs back.

    upload_2020-11-18_0-30-41.png

    upload_2020-11-18_0-30-59.png

    I also updated the code in my previous post above to make it easier for newcomers and also so that you can easily configure whether an actuator will only respond to one direction of force (i.e. 0 to 100 or 0 to -100) or else span the entire -100 to +100. The 2 servos devoted to sway and the 1 servo devoted to acceleration for the shoulders all operate on just one side of the DOF, i.e. they stay deflated until activated. Otherwise having constant pressure is a bit uncomfortable. However, for surge, the seat bottom and pedal bladder start at halfway, and inflate more for braking and deflate for acceleration. In this way you feel both the acceleration and braking in the feet, which really helps with the immersion.

    As for the office chair spin, I decided to devote it strictly to traction control. As mentioned above, my original approach caused the office chair spin that include some unwanted slack in it, but after looking at other traction control systems, I moved the servo off center and screwed a bolt into the seat connector. I recently noticed that the friction of the bolt and the seat connector was causing a little bit of metal dust particles to collect. To prevent this, I decided to wrap the bolt in electric tape so that the grooves wouldn't rub as much, and I think that did the trick.

    upload_2020-11-18_0-17-17.png



    I also added a cheap $20 four-point seat belt to the chair, which helps increase the realism by holding me back against the feel of the air bladders. However, it gets in the way of the Realteus pad, so I may have to fab something up.

    Next steps for version 1.3 (waiting on parts from Ebay and Amazon):
    1) Add servo to the wheel stand to pull the chair forward for surge
    2) Add servo seat belt tensioner
    3) Move to bucket-seat office gaming chair
    4) Wrap the air wedges with black spandex fabric to make them look like pillows and blend them into the chair

    Even though it only take about 3 minutes to set up the chair on the pad and hook everything up, it still is a bit tedious to hook up every day, especially if I only have a few minutes for a quick ride and then return to daddy duty, so I plan to set up a dedicated desk with a bucket gaming chair style. Kinda defeats the portability aspect a bit, but still I like that office chairs provide an easy and cheap hack for motion.

    To be continued in version 1.3...

    Attached Files:

    • Agree Agree x 1
    • Useful Useful x 1
  10. Banfy

    Banfy FR/AU

    Joined:
    Jun 11, 2020
    Messages:
    131
    Location:
    Australia
    Balance:
    299Coins
    Ratings:
    +55 / 1 / -0
    My Motion Simulator:
    DC motor, Arduino
    interesting idea, the wedge under the feet ;-)
    i might try this
    • Agree Agree x 1
  11. RacingMat

    RacingMat Well-Known Member Gold Contributor

    Joined:
    Feb 22, 2013
    Messages:
    2,234
    Location:
    Marseille - FRANCE
    Balance:
    20,890Coins
    Ratings:
    +2,083 / 21 / -2
    My Motion Simulator:
    2DOF, DC motor, Arduino
    great detailed post above!

    I watched the video: unfortunately there is still a lot of slack. This reduces the range of the actuator and induces a loss of precision in the movement.
    I'd advice you to look at this system "Turnbuckle Jaw" or "Rigging Screw"
    upload_2020-11-18_11-0-16.png
    here is a link: https://www.aliexpress.com/item/4000549880116.html
    Last edited: Nov 18, 2020
  12. Jumping Coin

    Jumping Coin Member Gold Contributor

    Joined:
    Aug 7, 2020
    Messages:
    93
    Balance:
    470Coins
    Ratings:
    +54 / 0 / -0
    Thanks for the advice and the link, @RacingMat ! Yep, there's still plenty of room (dare I say slack? lol) for improvement, and this will surely help. Thanks again!
    • Like Like x 1
  13. Jumping Coin

    Jumping Coin Member Gold Contributor

    Joined:
    Aug 7, 2020
    Messages:
    93
    Balance:
    470Coins
    Ratings:
    +54 / 0 / -0
    Just finished up version 3! The new version includes a surge mechanism and a seat belt tensioner. I've also migrated to a racing gaming chair, so I don't have to switch it back for work each time I'm done using it. I've also covered the air wedges with stretchy spandex so that they weren't such an eyesore.

    I took @RacingMat's advice and used an M4 turnbuckle jaw to connect the servo to the wheel spin. While there's still a little slack, the turnbuckle jaw removes much of it, and I don't notice it while driving. Also, in moving to the new gaming chair, I ditched the cutting board, and attached the 8 inch corner brace directly to the chair with zip-ties at the bottom of the chair and also to the bottom of the metal arm rests (the parts bolted to the seat).

    upload_2021-1-13_23-13-38.png

    The biggest upgrade has been to add a simple surge mechanism. One of the most annoying problems with an office chair is that it slides back when you hit the pedals. However, this doesn't have to be a problem, since that sliding is practically a free DOF for the taking. With this in mind, I attached two 60 KG servos to the wheelstand, which then connect to the chair via two additional M4 turnbuckle jaws, a zip tie, and a hook fastener for quick engagement/disengagement. Thus the mechanism pulls forward on acceleration and pushes backward on braking. Also, I decided to raise the pedals onto a milk crate for a better seating position.

    upload_2021-1-13_23-14-9.png


    Of course the handywork isn't super clean, but I tucked the Arduino and wires into an old to-go container, which I can snap on and off if I need to troubleshoot. I added another to-go container as a cover over the servos.

    upload_2021-1-13_23-14-30.png

    The movement is just a little over an inch in either direction (two inches combined), so it's not too much that I feel that my driving position is compromised. With only one 60 KG servo, it would stall under the pressure, but two servos working in unison operate just fine without any strain. The chair casters weren't too conducive to rolling, so I purchased $20 roller blade casters, and they glide smoothly. To retain the chair spin, I've kept two of the original caster wheels in the back and added ten 5/8-inch screw mounted metal ball bearings to the three 3x7 galvanized plates that hold the caster wheel stoppers.

    upload_2021-1-13_23-15-9.png

    upload_2021-1-13_23-15-24.png

    It works out well since the roller blade casters sit at 3 inches, about a half inch higher than the stock caster wheels, so the 5/8-inch ball bearings set everything level. The holes in the ball bearings fit perfectly with the holes in the three 3x7 galvanized plates I used to hold down the chair spin servo, so it was easy to match them up. While the metal ball bearings seem to work fine, I wonder if I should have used nylon ones instead, although I placed everything on a plastic mat anyway to prevent damage to the hardwood floor.

    As for the seat belt tensioner, I didn't do anything fancy; I just added two 35 KG servos to the back of the seat and added another to-go container stuffed with the Arduino and wires. It might work better with springs and a 6-point 3-inch harness, but my 4-point 2-inch seat belt was just $20, so I can't complain. The sides straps of the seat belt are fairly secure and don't rise up that much.

    upload_2021-1-13_23-15-41.png

    All told, I'm really satisfied with the end result. I spent about $750 in total, and while it's barely a 2-DOF machine, the spin, surge, g-seat, and seat belt tensioner can represent surge, sway, roll, heave, and traction loss; not too bad for just a bunch of clunky servos zip tied to an office chair. I also experimented with pitch since the chair has a rocking feature, but nothing seemed work. The rocking interferes with the chair spin, so I tightened up the rocking mechanism and nixed trying to get pitch for now.

    upload_2021-1-13_23-16-0.png

    I have to say that I'm really pleased with how well the surge works in conjunction with the g-seat! With just two inches of movement it feels surprisingly immersive. It also works well with the chair spin, so if the chair spins a bit, it will remain at an angle when moving forward and backward. And the seat belt has been a nice touch to pull it all together. In any case, I can now replicate that sudden stop-start-stop momentum all too familiar from my early days trying to learn to drive a manual. It feels good to be back in driver's ed again, lol.

    Here's a quick video of me fooling around on the track and evaluating some of the settings. (Apologies for the terrible driving!)



    Thanks again everyone for all your help!
    • Like Like x 4
    • Winner Winner x 2
    • Creative Creative x 2
    Last edited: Jan 14, 2021
  14. yura999

    yura999 New Member

    Joined:
    Aug 6, 2017
    Messages:
    23
    Balance:
    303Coins
    Ratings:
    +3 / 0 / -0
    My Motion Simulator:
    2DOF
    Great job friend:thumbs! I wanted to know how you set up the interface Settings? Show a photo of the interface Settings. And another question: what is the firmware used for seat belts? Thank you very much.
  15. Jumping Coin

    Jumping Coin Member Gold Contributor

    Joined:
    Aug 7, 2020
    Messages:
    93
    Balance:
    470Coins
    Ratings:
    +54 / 0 / -0
    Hi @yura999 ! Here is a screenshot of the interface settings.
    upload_2021-4-9_21-11-57.png

    I actually included the code base at the bottom of the first post on this thread. It includes instructions for where to modify the code to adapt it for your particular project. The code should work for any servo-based arduino project; I use the same code base (but different arduino boards) for the g-seat, the seat belt tensioner, and the surge mechanism on the wheelstand. (I could have used a single arduino, but then I'd need really long wires.) You'll just need to update the pins, the servo positions, etc.

    For convenience, here's the code base (with minor edits for a project with just 2 servos):

    Code:
    /************************************************/
    // Title:    Arduino Servo-based Simtools project
    // Function: For use with Simtools software, apply sway, surge, heave, traction loss
    // Code adapted from: https://www.xsimulator.net/community/threads/low-cost-2dof-3dof-6dof-motion-simulator-dof-reality.8570/page-43#post-166682,
    // which had been adapted from https://www.xsimulator.net/community/threads/rc-model-for-motion-simulation.4600/
    //
    /************************************************/
    /*
    Values for interface:
      Interface Type : Serial
      Comport : is at every individual
      BitsPerSec : 9600
      Data Bits : 8
      Parity : None
      Stop Bits : 1
      Bit Range : 8
      Output Type : Decimal
      Interface Output : L<Axis1a>~R<Axis2a>~
      Output Rate : 10ms
    Pins:
      4 = Left   (L)
      5 = Right  (R)
    */
    #include <Servo.h>
    /*******************************************************************************************
    Users may need to modify the below section. See variables:
        kActuatorCount
        kPins
        kActuatorName
        kPosAndNeg[kActuatorCount]
        kActuatorScale
    Please ensure that kActuatorCount matches the number of elements in the other variables in this section.
    *******************************************************************************************/
    // number of servos
    const int kActuatorCount = 2;
    // Initials for servos, must match Interface Output specified in GUI
    const char kActuatorName[kActuatorCount] = { 'L', //Left
                                                 'R' //Right
                                               };
    //Pin locations on Arduino board
    const int kPins[kActuatorCount] = {4, 5};
    /*kPosAndNeg allows you to specify whether a given servo will respond to only one side of a DOF, i.e. -100 to 0 or 0 to 100 (kPosAndNeg[i] = 0); or full range of a DOF, i.e -100 to 100 (kPosAndNeg[i] = 1).
     For example, if you only want the actuator to operate only on acceleration and not the braking for surge, then set kPosAndNeg[i] = 0
     If you want the actuator to activate across the whole range of acceleration and braking for surge, set kPosAndNeg[i] = 1
    */
    const int kPosAndNeg[kActuatorCount] = {0, 0};
    //safe position aka starting position.  For G-seat, I want servos as open as possible for safety reasons.
    int actuatorPosition[kActuatorCount]={0, 0};
    //Set range of position (i.e. servo range from 0 to 180)
    const int kActuatorScale[kActuatorCount][2] = {
                                                      {0, 180},
                                                      {0, 180}
                                                  };     
    /********************************************************************************************
    End of modification section.  No need to modify anything below for g-seat or servo-based simulators
    ********************************************************************************************/
    Servo actuatorSet[kActuatorCount];                  // our array of Actuators
    const char kEOL = '~';                              // End of Line - the delimiter for our acutator values
    const int kMaxCharCount = 3;                        // some insurance...
    // set up some states for our state machine
    // psReadActuator = next character from serial port tells us the Actuator
    // psReadValue = next 3 characters from serial port tells us the value
    enum TPortState
    {
      psReadActuator,
      psReadValue
    };   
    int currentActuator;                                // keep track of the current Actuator being read in from serial port
    int valueCharCount = 0;                             // how many value characters have we read (must be less than kMaxCharCount!!
    TPortState currentState = psReadActuator;
    void setup()
    {
        // attach the Actuators to the pins
        for (int i = 0; i < kActuatorCount; i++)
            actuatorSet[i].attach(kPins[i]);
        // initialise actuator position
        for (int i = 0; i < kActuatorCount; i++)
            updateActuator(i);
        
        Serial.begin(9600); // opens serial port at a baud rate of 9600
    }
    /*************************************************/
    void loop()
    {
    }
    /**************************************************/
    // write the current Actuator position to the passed in Actuator
    void updateActuator(int thisActuator) {
        int safePos;
        safePos=actuatorPosition[thisActuator];
        actuatorSet[thisActuator].write(safePos);
    }
    // this code only runs when we have serial data available. ie (Serial.available() > 0).
    void serialEvent() {
        char tmpChar;
        int tmpValue;
     
        while (Serial.available()) {
            // if we're waiting for a Actuator name, grab it here
            if (currentState == psReadActuator) {
                tmpChar = Serial.read();
                // look for our actuator in the array of actuator names we set up
                #ifdef DEBUG           
                  Serial.print("read in ");           
                  Serial.println(tmpChar);           
                #endif
                for (int i = 0; i < kActuatorCount; i++) {
                    if (tmpChar == kActuatorName[i]) {
                        #ifdef DEBUG           
                            Serial.print("which is actuator ");           
                            Serial.println(i);           
                        #endif
                        currentActuator = i;                        // remember which actuator we found
                        currentState = psReadValue;                 // start looking for the Actuator position
                        actuatorPosition[currentActuator] = 0;      // initialise the new position
                        valueCharCount = 0;                         // initialise number of value chars read in
                        break;
                    }
                }
            }
          
            // if we're ready to read in the current Actuator's position data
            if (currentState == psReadValue) {
                while ((valueCharCount < kMaxCharCount) && Serial.available()) {
                    tmpValue = Serial.read();
                    if (tmpValue != kEOL) {
                        tmpValue = tmpValue - 48;
                        if ((tmpValue < 0) || (tmpValue > 9)) tmpValue = 0;
                        actuatorPosition[currentActuator] = actuatorPosition[currentActuator] * 10 + tmpValue;
                        valueCharCount++;
                    }
                    else break;
                }
              
                // if we've read the value delimiter, update the Actuator and start looking for the next Actuator name
                if (tmpValue == kEOL || valueCharCount == kMaxCharCount) {
     
                    #ifdef DEBUG           
                        Serial.print("read in ");           
                        Serial.println(actuatorPosition[currentActuator]);           
                    #endif
     
                    //if kPosAndNeg[i] == 0, then apply servo to only one side of a DOF (i.e -100 to 0 or 0 to 100)
                    if (kPosAndNeg[currentActuator] == 0)
                    {
                        //No -ve on G-seat : 90 = middle
                        if (actuatorPosition[currentActuator]<127)
                        {
                            actuatorPosition[currentActuator]=127;
                        }
                        // scale the new position
                        // Range is now 0 - 255
                        // Maps between min and max
                        actuatorPosition[currentActuator] = map(actuatorPosition[currentActuator], 127, 255, kActuatorScale[currentActuator][0], kActuatorScale[currentActuator][1]);
                    }
                    //else kPosAndNeg[i] == 1, so apply servo to full range of DOF (i.e. -100 to 100).
                    else
                    {
                        actuatorPosition[currentActuator] = map(actuatorPosition[currentActuator], 0, 255, kActuatorScale[currentActuator][0], kActuatorScale[currentActuator][1]);
                    }
                  
                    #ifdef DEBUG           
                        Serial.print("scaled to ");           
                        Serial.println(actuatorPosition[currentActuator]);           
                    #endif
     
                    updateActuator(currentActuator);
                    currentState = psReadActuator;
                }
            }
        }
    }
    I've made a few improvements since the last post, and I'm hoping to do a writeup soon, but just a heads up that I switched the seat belt tensioner to use 60 kg servos rather than 35 kg ones, since I ended up breaking two of the 35 kg servos. I'm now using four 60 kg servos; one for each shoulder and one for each hip belt. I attached the shoulder servos to the chair pedestal, which actually does a better job at spinning the chair than my initial design. I also attached a furniture dolly to the pedals, so the pedals move in conjunction with the seat (the wheelstand is still stationary). Hoping to write up a post on it in the next week or so.

    I look forward to your project!
    • Informative Informative x 1
  16. Jumping Coin

    Jumping Coin Member Gold Contributor

    Joined:
    Aug 7, 2020
    Messages:
    93
    Balance:
    470Coins
    Ratings:
    +54 / 0 / -0
    Time for another update!

    TLDR:
    • Moved pedals to dolly so they can move with chair
    • Changed mechanism for spinning chair; shoulder belts are connected to servos on chair pedestal, which turn the chair when belts are pulled
    • Added hip belt tensionsers
    • Added belt to pull sideways for traction loss / roll
    • Added slight pitch to chair
    • Added third air wedge to each servo for gseat

    One of the biggest changes is that I attached the pedals to a dolly (15 inch x 15 inch) using velcro so that the pedals now move along with the seat. My feet were getting a bit tired from fighting the servos as they pushed against me, and this way feels much smoother. Also, the servos pulling the seat were starting to run a bit hot from having to fight against the force of my legs and then getting too much of a boost from the force. The dolly fixes that. The dolly is also connected to the servos via zipties so that it moves with them. The chair now slides backward for acceleration and forward for braking, which I find improves immersion by throwing me backward into the air wedges during acceleration. Granted, this implementation requires my feet to rest against the dolly to work correctly, and the steering wheel is still fixed, but these are totally acceptable compromises for me. In fact, having the steering wheel fixed means that when I brake, the steering wheel and pedals feels heavier because I'm pushed forward.

    upload_2021-6-24_17-24-1.png

    To keep the dolly straight, I could have purchased stationery wheels, but since I'm a cheapskate with a lot of zipties, I just ziptied the wheels in place instead. I also ziptied two 16 inch drawer slides to the wheelstand and the dolly to use as linear rails for reinforcing the forward-backward movement and preventing side-to-side movement; not completely necessary but they do help a bit. I've recently switched to T-LCM pedals with load cell brake, and it seems to work fine even with the velcro, although if I intentionally pound the brake super hard it lifts the front end of the dolly about an inch. Not a whole lot that it's bothersome, but if it does get annoying I'm sure I can ziptie something to improve it.

    upload_2021-6-24_17-21-54.png

    Another big change was made in the mechanism for spinning the chair. Previously, it was difficult to get the servo for spinning the chair perfectly centered. Also, I couldn't turn the chair without moving the servo arm, so it was a little challenging to get in and out of the seat. I fixed this by integrating the chair spin with the shoulder seat belt tensioners by attaching the servos to the chair's pedestal. Now, when the shoulder tensioner pulls, it spins my seat in the direction of the turn. I added tensioning hip belts as well, but I attached those to the back of the chair rather than the pedestal. (If both shoulder and hip belts were attached to the pedestal, it increases the range of the spin, but severely diminishes the tensioning of the seat belt.) The chair only spins about 15 degrees in each direction, and from an outside perspective it looks like less movement than before. However, when paired with the air wedges and tensioning shoulder and hip belts, I really feel pressed into the side of my seat when cornering. If I fight against the force of the spin, instead of stalling the servo, it just increases the tensioning of the seat belt, and forces me to engage my core muscles, further accentuating the turn.

    Here's a pic of the servo pulling the shoulder belt (In case it helps there is one pedestal leg centered in the front, and these servos are on the legs adjacent to the front leg.):

    upload_2021-6-24_17-25-15.png

    And here's a pic of the hip belts. (They're attached to the 8 inch corner brace originally used for spinning the chair):
    upload_2021-6-24_17-29-13.png

    Since the seat belt now controls the spin, loosening the belts allows the seat to rotate easily for getting in and out of it. I've changed the settings to use the chair spin exclusively for sway; using it for traction loss just didn't feel right because the pivot point is centered rather than in front. Also, several of the 35 kg servos originally used for the seat belts broke; so from here on out everything is exclusively 60 kg servos.

    I also added a third air wedge to each of the servos pushing the g-seat air wedges. In case it helps, I found M3 Machinery Shoulder Lifting Forged Eye Bolt 304 amazon.com/gp/product/B08F7S6H9F, which work great for connecting the servos to zip-ties.

    Currently, I'm experimenting with traction loss and a little bit of pitch. For traction loss, the best I could do so far was attach servos to the bottom of each arm rest and then connect it to a belt. When the traction loss kicks in, it pulls me sideways. I've also found that this serves as a good proxy for roll in flight sims. It's not perfect, but it works surprisingly well in simulating roll.

    upload_2021-6-24_17-31-30.png

    I want to eventually play around with some flight sims, so I've been experimenting with adding a touch of pitch to the seat. I may eventually switch to a more elegant approach, but for now I've attached two servos to a plastic cutting board under the back cushion, which together push a bigger cutting board. I used a single-sided servo arm and then screwed two of the circle servo horns to it, so that it rolls when pushing the seat forward. In this way, the servo only needs to rotate 90 degrees and pushes the seat about 2 inches forward. Not a whole lot, but enough to get a decent sense of pitch when paired with an air wedge under my thighs that inflates when the seat goes back. I have to put these servos a bit higher up on chair back than ideal, closer to my shoulders than my lower back. Otherwise, they get overworked and pretty hot due to the pressure from me getting thrown back into the seat and air wedges. At shoulder level, I think they should work fine.

    upload_2021-6-24_17-32-48.png

    Here are some quick samples of the chair in action. (The servos are by no means quiet, but not nearly as loud in real life as they sound in the videos.)

    Surge (rolling chair forward and backward). You might hear a tapping sound when the seat is pushed forward all the way. That's the dolly wheels hitting the edge of the wheelstand pedal area. Under normal use it generally doesn't reach the limit, but if it gets bothersome I may reposition it a bit.





    Sway (by pulling the shoulder belts)


    Traction loss / roll


    Pitch
    https://youtu.be/kNTn5VMEPwQ
    https://youtu.be/wt3CNmXeGwI
    https://youtu.be/thj8bcHcsSw

    And here's a quick test of the rig in action, prior to the pitch and traction loss additions
    https://youtu.be/_rQuOENebsM


    To summarize, I'm now using a total of 14 60kg servos (4 for g-seat, 4 for seat belt (2 of which spin the chair), 2 for sliding forward/backward, 2 for traction loss, and 2 for pitch). It's a rather silly chair and nowhere near as magnificent as many of the showcases on this site, but it's super-immersive and totally accessible for entry-level enthusiasts like myself since the servos are practically plug and play. Of course more powerful motors may do a much better job and/or cost less than 14 x ($25 servo + $15 DC adapter per servo) = $560. However, for me, it suitably represents surge, sway, heave, pitch, and traction loss/roll, while using minimal hardware by taking advantage of the inherent movement of an office chair and wheelstand. All in all, I'm having a blast! Thanks everyone for all your help!

    Attached Files:

    • Like Like x 2
    • Creative Creative x 1
    Last edited: Jun 25, 2021
  17. Banfy

    Banfy FR/AU

    Joined:
    Jun 11, 2020
    Messages:
    131
    Location:
    Australia
    Balance:
    299Coins
    Ratings:
    +55 / 1 / -0
    My Motion Simulator:
    DC motor, Arduino
    Very nice and surprising that you managed to get chair motion capabilities out of those servos
    Next step is a dolly under the wheel i guess ;-)
  18. Jumping Coin

    Jumping Coin Member Gold Contributor

    Joined:
    Aug 7, 2020
    Messages:
    93
    Balance:
    470Coins
    Ratings:
    +54 / 0 / -0
    Hi everyone,

    Here's a updated video with everything working together after a little bit of tuning:
    • Like Like x 2
    • Winner Winner x 2
  19. JBung

    JBung Just a friendly chap

    Joined:
    Mar 13, 2021
    Messages:
    19
    Occupation:
    Mechanical Fitter/Scheduler/Systems Analyst
    Location:
    New Zealand
    Balance:
    71Coins
    Ratings:
    +17 / 0 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino, Motion platform
    This is cool, thinking outside the box.:thumbs
  20. Jumping Coin

    Jumping Coin Member Gold Contributor

    Joined:
    Aug 7, 2020
    Messages:
    93
    Balance:
    470Coins
    Ratings:
    +54 / 0 / -0
    Time for a new update! It's a bit of a stretch, but I can actually say that it's now a (somewhat) 6ish DOF g-seat!

    TLDR:
    1) Added a g-headband for acceleration, which has dramatically helped with VR motion sickness in racing!
    2) For flight, added pitch via a paddles for pitch up and belt pulling feet for pitch down, which has also dramatically helped with VR motion sickness in flying!
    3) Added roll by pivoting the pedals along with a seat belt harness by the ribs.
    4) Added actual traction loss by pulling the rear caster wheels sideways as well as spinning the wheelstand to allow for a pivot point at the feet.
    5) Added rumble motors to pedals and shifter.

    Here's a quick spin. Since most of the effects are via belts and airbags, it's a little hard to demonstrate it well via a video.


    Details:
    1) G-headband! Inspired by all of the amazing g-head and g-helmet ideas such as @Banfy (https://www.xsimulator.net/communit...-sim-rig-with-g-seat.14948/page-4#post-213785), @lap345 (https://www.xsimulator.net/community/threads/low-cost-head-motion.9233/), and @sberns (https://www.xsimulator.net/community/threads/g-head-bowden-cable-based-surge-system.15046/), I wanted to see what would happen if I strapped a servo to a simple headband to simulate acceleration forces...and wow, what an effect! I connect a relatively elastic headband to a servo with some nylon string, which pulls about 2 inches. The short travel combined with the stretchiness of the headband means that my head isn't whipped back, but instead is progressively pulled as with a rubberband. I'm new to VR, so I'm still apt to get some motion sickness. However, with a g-headband, I can race for much longer periods. I keep the string relatively loose; loose enough that I can freely turn my head without it getting too taut. The servo actually doesn't pull too hard, but strong enough to engage my neck muscles, which has had a profound effect in reducing my VR motion sickness. Also, the headband easily fits under an Oculus Quest 2 headset without needing to directly connect the headband and headset. Since the headband is pulled independent of the headset, there's no need to reinforce the headset to withstand the force. I used a spare 60 KG servo that I had laying around, though a lesser servo would likely work just as well.



    2) Pitch up and down: For flight simming, I attached two metal plates via door hinges and a servo to push/pull the plates. When pitching up, the plate pushes my feet upward. When pitching down, a belts pulls down on my ankles, making my feet really heavy. Also when pitching up, the rib harnesses pull down to simulate tilting backward, and when pitching down, the hip tensioners pull down to simulate tilting forward. While not as good as real pitch, it's pretty convincing.




    3) Roll: I added roll by mounting the pedals onto a 2 inch thick pvc pipe, which rotates about 30 degrees in each direction. A 60 KG servo pulls rolls the pedals using the pvc pipe as a fulcrum/wheel. The seat itself is stationary, but I added a wobble cushion, which tilts slightly when you lean. A wobble cushion is great for exaggerating the motion since you're basically sitting on a rolling disk of air. Also, a side rib harness pulls down during roll (or sway for simracing), giving a sustainable feel of roll that feels really immersive. I've been using a four point harness, which can be known to slide up. However, these extra tensioners hold the seat belt in place without needing a full six point harness. In effect it sort of becomes a six point harness, albeit the fifth and sixth points are attached to the ribs rather than the thighs.



    4) Traction Loss: I've been pondering how to add true traction loss to my chair for awhile now. I've tried a lot of things and settled on two 60 KG servos; one that spins the wheelstand as a pivot point in the front and one that pulls the chair sideways via the back two wheels. The wheelstand spins via furniture rollers angled around the wheelstand, and a 60 KG servo attached between the front caster wheel and two 16 inch drawer slides that serve as linear rails. The sideways movement occurs via a 60 KG servo attached to two 8 inch drawer slides on some plywood. The traction loss was interfering with the surge movement since the rear wheels would turn sideways and limited the forward/backward slide, so I propped the rear wheels up on additional furniture rollers attached to old cutting boards. The backend only moves about 1.5 inches in either direction, but that's plenty enough for me. For racing, I repurposed the shoulder and hip seat belts to be used for traction loss so that the effect feels like much larger movements than it really is.

    Rear traction loss: https://youtu.be/x7ZdfTs9J7U
    Spinning wheelstand as a front pivot: https://youtu.be/twyfXb0Lijo

    5) Rumble Motors: Added xBox controller rumble motors to each pedal and the shifter using SimHub. Much easier than I expected.

    While I don't generally represent all 6 DOFs at a given time (so that I can focus on those most useful in a game), the chair, airbags, and belts contribute to movement in somewhat 6 DOFs, with much of it being sustainable forces that persist through the entirety of the maneuver:

    1) Surge: the chair itself slides forward/backward, accompanied by hip and rib belts (sustained force), and air bags at feet and hips (sustained force)
    2) Sway: the chair moves sideways, along with side air bags (sustained force)
    3) Yaw: the chair rotates via belts connected to chair pedestal (sustained force), and the wheel stand spins.
    4) Pitch: The chair back cushion slightly pitches backward and forward, accompanied by a belt at the feet for pitch down (sustained force) and paddle at the feet for pitch up (sustained force)
    5) Heave: All airbags have 30% devoted to heave (sustained force)
    6) Roll: The pedals roll sideways, accompanied by rib belts (sustained force)

    So, now it's a kinda sorta 6ish DOF g-seat, albeit I take some artistic liberties in saying so. Of course, I'm not pretending this is on par with the likes of a stewart platform, but still a lot of fun. Now I just need to focus on cable management. :think
    • Creative Creative x 2