Head G-Force Simulation

Running simulator build projects.
Please use the image gallery for your pictures, a short tutorial can be found here.
The first image in the first post will be shown in the project gallery.

Head G-Force Simulation

Postby EICH » Wed 14. Jun 2017, 11:34

Hi Guys

I want to show you my first prototype of my Head G-Force Simulation Seat.

It is far from perfect, but i learned a lot.

Idea:
The Idea came to me, when i heard, that a lot of Formula 1 drivers have to have really good neck muscles, and that it is near impossible to withstand those forces as a normal human beeing.
I also recognised, that the normal 2 DOF Motionseats, whiche tilt around a point beneath the seat, have the problem, that they lie to you in the first instance. The problem is, that if you are making a right turn, then the seat has to tilt to the left, so the gravitatinal field can line up with the acceleration field of the game. But to get there, you have to accelerate the Seat to the left, so you will feel a push from the right, which isn't, what you would feel in the car.
A solution to this problem is to move the tilting point of the Seat above the head of the driver. But because you can't put the tilting point as high as you want, the head feels less of an acceleration, if the seat is accelerated, than your feet. A solution to this, could be a seperate G-Force simulation for the head.

The Seat:
It is a really simple construction, as you can see in the pictures. There is a electric motor, which pulls on a cable to simulate the g-forces. The cable is guided by the 4 rollers and is attached to a quick chanche mechanism. This is to chanche helmets, to accomodate for different head sizes.
The whole consturction with the electric motors and the two arms can be moved up and down, so different people with different heights can enjoy the experiace.

436543664367436843694370


Controll
The electric motor is controlled by an Arduino Uno with an H-Bridge. The code is written by myselve. It is a DC motor with 75 W (30 V, 2.5 A). The h-Bridge is an LN298N.
I use the USO setup in the sim converter to talk to the Arduino. The Arduino read the COM Port and controlls the Motor. Sadly at this point, i wasn't able controll it with the PID-controller. So right now, the values are just set to the output of the Arduino, as a pwm signal.
It works better than i thought, but it doesnt acctually controll the foce, it controlls the speed of the motor. But with the resistance of the motor and the controll voltage the current is proportional to the voltage, which results in a proportional force but only if the motor isnt turning. As soon as the motor starts to spin, the current as well as the force will drop.
My goal is to controll the current and therefore controll the force.

As for the electrical circuit, i just jused the circuit proposed in figure 6 in the datasheet of the LN298N. https://www.sparkfun.com/datasheets/Robotics/L298_H_Bridge.pdf

4371

X-Sim USO Setup
Here is my USO Setup in the X-Sim converter.
4372

To check the COM Port i used a free trial version of Device Monitoring Studio. But you can also use an other serial port sniffing, analyzer programm.


Material:
I got the racing seat from my uncle, who drives actual racing cars. As you can see, it is a pretty old one.
The motor is from ricardo.ch (swiss ebay)
Right now, i use an Arduino Uno
Most of the electric components are from a local electronics shop.
To drive the car, i use my G27 steeringwheel.
To power the motor, i use my Lab Powersuply, but at some point i want to swith to an other one.
The Helmets i got from a local motorcylce store for free. Those are old helmets, which aren't save any more to use on the street.

Code:
And here is my current code for the Arduino.

Code: Select all
//#include <PWM.h>
//int32_t frequency = 25000; //frequency (in Hz)

#include <PID_v1.h>



#define serialBuffersize 8

#define debug 0

int ledPin = 8;

// 75459507 = Max x-sim g-force Value for RBR
// 1000000  = Max x-sim g-force Value for GTR2



// Pin Setup Motorcontroll
int MotorInput1_Pin = 2;
int MotorInput2_Pin = 3;
int Motor_pwm_Pin = 11;
int currentsense_Pin = A0;


// PID Motorcontroll
int Voltage_currentsense = 0;
double Setpoint, Input, Output;                                          //I/O for PID
double aggKp=20, aggKi=0, aggKd=2;                                      //original: aggKp=40, aggKi=2, aggKd=10, Aggressive Turning,50,20,20
double consKp=10, consKi=20, consKd=1;                                    //original consKp=20, consKi=1, consKd=5, Conservative Turning,20,10,10
PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT);  //Initialize PID

int MotorForce = 0;

// Serial data handling
char serialBuffer[serialBuffersize];
String command;
boolean Datastart = false;
int serialIndex = 0;
int setForce = 0;
int oldsetForce = 0;


int whilelooper = 1;

void setup() {
  Serial.begin(115200);


  //Pin Setup Motorcontroll
  pinMode(MotorInput1_Pin, OUTPUT);
  pinMode(MotorInput2_Pin, OUTPUT);
  pinMode(Motor_pwm_Pin, OUTPUT); 
  pinMode(currentsense_Pin, INPUT);

  digitalWrite(MotorInput1_Pin, LOW);
  digitalWrite(MotorInput2_Pin, LOW);
  digitalWrite(Motor_pwm_Pin, LOW); 

  // PID Motorcontroll
  myPID.SetMode(AUTOMATIC);
 
  pinMode(ledPin, OUTPUT);


  digitalWrite(ledPin, LOW);

}




void loop() {
  while (whilelooper == 1){
  while(Serial.available() > 0){
    char charBuffer = Serial.read();     //string from USO --> L~a01~E 8bit resolution\decimal output
   
          #if debug   
      Serial.print("charBuffer read: ");
      Serial.println(charBuffer);   
          #endif   
    if (charBuffer == 'E'){              // E marks end of dataset from x-sim
      command = String(serialBuffer);
          #if debug     
      Serial.println("serialBuffer");
      Serial.println(serialBuffer);
      Serial.println(command);
          #endif     
      for( int i = 0; i < sizeof(serialBuffer);  ++i ){
        serialBuffer[i] = (char)0;
      }
      serialBuffer[serialIndex] = 0;
      Datastart = false;
      serialIndex = 0;
          #if debug
      Serial.println("new serialBuffer");
      Serial.println(serialBuffer);
          #endif           
    }
    else if (Datastart == true && isDigit(charBuffer) > 0){
          #if debug
      Serial.print("charBuffer aufbau: ");
      Serial.println(charBuffer);
          #endif     
      serialBuffer[serialIndex++] = charBuffer;
          #if debug
      Serial.print("serialBuffer aufbau: ");
      Serial.println(serialBuffer);
          #endif           
    }
    else if (charBuffer == 'S'){         // S marks start of dataset from x-sim
       Datastart = true;
          #if debug
       Serial.print("Serialbuffer S: ");
       Serial.println(serialBuffer);
          #endif       
    }   
  } //end while(Serial.available() > 0)

 
 
  setForce = command.toInt();
  command = "";
 
  if (setForce > 0 && setForce != oldsetForce){
    oldsetForce = setForce;
    setForce = 0;
    /*
    Serial.print("command: ");
    Serial.println(command);   
    Serial.print("Data: ");
    Serial.println(oldsetForce);
    Serial.println("---------------------------------------");
    */
  }
 
  if (oldsetForce >= 127){
    MotorForce = abs(oldsetForce-127)*2;
    digitalWrite(ledPin, HIGH);
    digitalWrite(MotorInput1_Pin, HIGH);
    digitalWrite(MotorInput2_Pin, LOW);
  } else {
    MotorForce = abs(127-oldsetForce)*2;
    digitalWrite(ledPin, LOW);
    digitalWrite(MotorInput1_Pin, LOW);
    digitalWrite(MotorInput2_Pin, HIGH);   
  }

  Voltage_currentsense = analogRead(currentsense_Pin);
  Input = Voltage_currentsense/4;
  Setpoint = MotorForce;
  //myPID.Compute();
  /*Serial.print("Setpt:  ");
  Serial.println(Setpoint);
  Serial.print("Input:  ");
  Serial.println(Input);
  Serial.print("Output: ");
  Serial.println(Output);
  //delay(1000);
  */
 
  //Serial.print("MotorForce: ");
  //Serial.println(MotorForce);
  analogWrite(Motor_pwm_Pin, MotorForce);
  //Serial.print("currentsense: ");
  //Serial.println(Voltage_currentsense); 

 
} // end while (whilelooper)
} //end void loop()


Improvements:
Because the force on the helmet is insertet on the top, it can get quite uncomfotable, because the resulting torque wants to rotate the helmet around your head. My decision, to put it on top was, because it is easier to build a quickchanche mechanism and because i wanted to try to drive with an Oculus Rift DK2. This works with 2 out of 3 helmets. Those helmets are socalled jet helmets. The one, which doesn't work, is an integral helmet. Because of the Oculus Rift, i thought, i can't attache the cable to the side of the helmet, because you want to be able to look around. But because most of the time i use the seat with a monotor, i would attache the cable on the side.
The current roller guides for the cable have a really big friction, which also chanches drastically if, the cable isn't perfectly alligned.
As for now, i can only simulate lateral forces.

The project is very much still in progress and i will post future chanches/improvements here.
I hope it was interessting and you got some information out of it. I am open for ideas, critics and nice replyes.
Greetings from Switzerland
EICH
 
Posts: 3
Images: 8
Joined: Thu 11. May 2017, 16:18
Has thanked: 0 time
Been thanked: 0 time

Return to Motion simulator Projects in progress

Who is online

Users browsing this forum: No registered users and 5 guests