Flight Simulator Project

Hi all,

My students have been given the chance to build a flight simulator.

Ideally we would build a prototype for April, we have obtained a decent desktop computer with Prepar3d which is Lockheed Martins own software for its pilot training program.

We have a flight yoke and intend to have the prototype frame, made of wood, to change position according to the movement of the yoke.

There are some resources online, for example there are some programs that can read joystick movements directly from windows and that then talk to Arduino.

The idea is that then the Arduino could control a series of servos or linear actuators and move the 'pod' containing the pilots.

I have an Arduino starter set and a relay board incoming.

I need help with ideas how to draw info from the yoke, how to change that information into something that Arduino can understand and then instruct a series of four servos to move.

Appreciate all your help and advice,

Steve Price
Head of Science
Elutec College
London

That should be a function of the simulation software. The movement of the motionbase is not directly controlled by the yoke. It is supposed to represent the movement of the aircraft, which is controlled by the yoke but also subject to other inputs like wind and ground.

It's a fairly common thing to do, to get an output from the simulation software and represent that on a physical device with an Arduino or other small microcontroller acting as an interface. You just need to identify the correct simulation variables (pitch, roll etc) and a method for getting them out of the simulation (USB?) and an Arduino that can process this and command actuators to move, then you need the actuators.

How many students? Can you assign each of those tasks to a different student?

Hi,

I've got a team of about twelve, ranging from 14 - 18 years old, some of them are very proficient at Python, most are unused to Arduino but it seems more accessible.

Currently I have them in four groups, one researching, one building the frame for the 1:8th scale model, one learning how to use the software for the simulation and the last team on publicity - we've tried to get some local support but no interest from local ICT firms as yet.

The software does have a developer kit but it seems to be if people want to upload new mods to the game.

We cant seem to find an output from the game as yet.

  • SimConnect SDK can be used by programmers to write add-on components and access complete simluation data

Looks like the functionality is there. Now you just need a communication protocol to send out the relevant data to the hardware team, so they can program their Arduino.

Hello, I can't comment about Prepar3d as I'm not familiar with that software. It sounds to me like you're trying to build a multi axis flight simulator platform, if so how many axis'? Have you considered a Stewart platform? Take a look of some of these videos for inspiration! Douwe Jippes - YouTube. In my project I'm using Microsoft Flight Sim X and program called BFF motion driver. It reads outputs from Flight Sim X and converts them to motion cues that then are sent to the Arduino via usb cable. I wrote a small program for the Arduino that reads the inputs and converts it to PWM outputs that are sent to a high current H-bridge that power linear actuators. I hope this helps. Good luck!

Hi Tetris,

that's exactly the type of thing we'd like to produce, I am currently learning about H bridges and relays so that I can get a appropriate sized linear actuator for the prototype that will be shield effectively from the Arduino.

We have got a copy of Flight simulator too, and I think we might be better off starting with that - Prepar3d looks nicer and is fun to fly but we are struggling with the SDK software at the moment.

I've looked at Stewart platforms and my only concern would be the weight component and how much that type of layout would take when scaled up human size - the prototype needs to reflect the full size model if we win the right from Boeing to build the real thing (its an inter school competition).

We are currently looking to have four linear actuators (one in each corner of the flight pod) that we control via the Arduino and relay circuit, but it seems the tricky part is getting the signal from the game to the Arduino and positioning these with the joystick movements.

How long did it take to code your own program? I've seen one guy on youtube who did it for his PhD! This worries me a bit as we are going to be short on time!

oh and we are only aiming to have 3DOF for now!

Might not need four actuators come to think of it - we don't need to move much, just enough to give the sensation of movement, so one actuator at the front (two if the load is too great) and two at the back in each corner.

I've started reading through Xsimulator forums but there isn't much on there about coding for Arduino.

they are really good at the hardware side of things, and they even have some link software for P3D, I just need about three years to learn the electronics again!

A big problem may be that the game/simulator software is not designed to interface with any other hardware beyond input from a joystick or game controller. Have you verified the software has the desired I/O capabilities with an arduino?

I'd start out with a 2DOF rig (pitch and roll) and expand from there. I built a small proof of concept actuator about 6 months ago and I have just finished a full size prototype. I'm still waiting for a SoftPot Membrane Potentiometer for the position feedback. As for the program do you want me to post it or do you want your students to do it themselves?

if you could post it we'd be very grateful!

Here's the code, I hope it's useful.

/*BFF motion software reader and driver for Arduino v1.0 by R Cummins.
Even pins are for actuator 'extend' and odd pins are for actuator 'retract'.
Credit to Brett Beauregard for his excellent PID library. Some code also by
Brett Beauregard from his PID adaptive tuning example. Code is free to use.
Remember code must be tuned to whatever device(s) you're attempting to control.
Enjoy!
*/

#include <PID_v1.h>

int cr, count=1, pin, c, time=5, retlimit=150, exlimit=850;
int sread[9];
//Define Variables we'll be connecting to
double Input, Output1, Output2, Output3, Output4, Output5, Output6, Setpoint, gap;
//Define the aggressive and conservative Tuning Parameters
double aggKp=1.2, aggKi=0.070, aggKd=0.365;
double consKp=0.125, consKi=0.015, consKd=0.08;

//Specify the links and initial tuning parameters
PID act1PID(&Input, &Output1, &Setpoint, consKp, consKi, consKd ,DIRECT);
PID act2PID(&Input, &Output2, &Setpoint, consKp, consKi, consKd ,DIRECT);
PID act3PID(&Input, &Output3, &Setpoint, consKp, consKi, consKd ,DIRECT);
PID act4PID(&Input, &Output4, &Setpoint, consKp, consKi, consKd ,DIRECT);
PID act5PID(&Input, &Output5, &Setpoint, consKp, consKi, consKd ,DIRECT);
PID act6PID(&Input, &Output6, &Setpoint, consKp, consKi, consKd ,DIRECT);

void setup()
{
Serial.begin(9600);
for (c=2; c<14; c++)
{
pinMode(c, OUTPUT);
}
act1PID.SetMode(AUTOMATIC);
act1PID.SetSampleTime(time);
act2PID.SetMode(AUTOMATIC);
act2PID.SetSampleTime(time);
act3PID.SetMode(AUTOMATIC);
act3PID.SetSampleTime(time);
act4PID.SetMode(AUTOMATIC);
act4PID.SetSampleTime(time);
act5PID.SetMode(AUTOMATIC);
act5PID.SetSampleTime(time);
act6PID.SetMode(AUTOMATIC);
act6PID.SetSampleTime(time);

}

void loop()
{
if (Serial.available()>0)
{
cr=Serial.read();
if (cr==65)
{
do
{
if (Serial.available()>0)
{
sread[count]=(Serial.read());
count++;
}
}
while(count<9);
}
}
if (sread[1]==66)
{
//--------------------------------------------------actuator 1
Setpoint=sread[3];
//Setpoint=100;
Setpoint=map(sread[3], 0, 255, retlimit, exlimit);
//Setpoint=((Setpoint+1)*2.35)+100;
Input = analogRead(0);

if (Setpoint > Input)
{
act1PID.SetControllerDirection(DIRECT);
analogWrite(3, LOW);
pin=2;
}
else
{
act1PID.SetControllerDirection(REVERSE);
analogWrite(2, LOW);
pin=3;
}
gap = abs(Setpoint-Input); //distance away from setpoint
if(gap<6)
{ //we're close to setpoint, use conservative tuning parameters
act1PID.SetTunings(consKp, consKi, consKd);
}
else
{
//we're far from setpoint, use aggressive tuning parameters
act1PID.SetTunings(aggKp, aggKi, aggKd);
}

act1PID.Compute();
if (gap<2)
{
Output1=0;
}
analogWrite(pin, Output1);
//--------------------------------------------------actuator 2
Setpoint=sread[4];
Setpoint=map(sread[4], 0, 255, retlimit, exlimit);
Input = analogRead(1);
if (Setpoint > Input)
{
act2PID.SetControllerDirection(DIRECT);
analogWrite(5, LOW);
pin=4;
}
else
{
act2PID.SetControllerDirection(REVERSE);
analogWrite(4, LOW);
pin=5;
}
gap = abs(Setpoint-Input); //distance away from setpoint
if(gap<6)
{ //we're close to setpoint, use conservative tuning parameters
act2PID.SetTunings(consKp, consKi, consKd);
}
else
{
//we're far from setpoint, use aggressive tuning parameters
act2PID.SetTunings(aggKp, aggKi, aggKd);
}

act2PID.Compute();
if (gap<2)
{
Output2=0;
}
analogWrite(pin, Output2);
//--------------------------------------------------actuator 3
Setpoint=sread[5];
Setpoint=map(sread[5], 0, 255, retlimit, exlimit);
Input = analogRead(2);
if (Setpoint > Input)
{
act3PID.SetControllerDirection(DIRECT);
analogWrite(7, LOW);
pin=6;
}
else
{
act3PID.SetControllerDirection(REVERSE);
analogWrite(6, LOW);
pin=7;
}
gap = abs(Setpoint-Input); //distance away from setpoint
if(gap<6)
{ //we're close to setpoint, use conservative tuning parameters
act3PID.SetTunings(consKp, consKi, consKd);
}
else
{
//we're far from setpoint, use aggressive tuning parameters
act3PID.SetTunings(aggKp, aggKi, aggKd);
}

act3PID.Compute();
if (gap<2)
{
Output3=0;
}
analogWrite(pin, Output3);
//--------------------------------------------------actuator 4
Setpoint=sread[6];
Setpoint=map(sread[6], 0, 255, retlimit, exlimit);
Input = analogRead(3);
if (Setpoint > Input)
{
act4PID.SetControllerDirection(DIRECT);
analogWrite(9, LOW);
pin=8;
}
else
{
act4PID.SetControllerDirection(REVERSE);
analogWrite(8, LOW);
pin=9;
}
gap = abs(Setpoint-Input); //distance away from setpoint
if(gap<6)
{ //we're close to setpoint, use conservative tuning parameters
act4PID.SetTunings(consKp, consKi, consKd);
}
else
{
//we're far from setpoint, use aggressive tuning parameters
act4PID.SetTunings(aggKp, aggKi, aggKd);
}

act4PID.Compute();
if (gap<2)
{
Output4=0;
}
analogWrite(pin, Output4);
//--------------------------------------------------actuator 5
Setpoint=sread[7];
Setpoint=map(sread[7], 0, 255, retlimit, exlimit);
Input = analogRead(4);
if (Setpoint > Input)
{
act5PID.SetControllerDirection(DIRECT);
analogWrite(11, LOW);
pin=10;
}
else
{
act5PID.SetControllerDirection(REVERSE);
analogWrite(10, LOW);
pin=11;
}
gap = abs(Setpoint-Input); //distance away from setpoint
if(gap<6)
{ //we're close to setpoint, use conservative tuning parameters
act5PID.SetTunings(consKp, consKi, consKd);
}
else
{
//we're far from setpoint, use aggressive tuning parameters
act5PID.SetTunings(aggKp, aggKi, aggKd);
}

act5PID.Compute();
if (gap<2)
{
Output5=0;
}
analogWrite(pin, Output5);
//--------------------------------------------------actuator 6
Setpoint=sread[8];
Setpoint=map(sread[8], 0, 255, retlimit, exlimit);
Input = analogRead(5);
if (Setpoint > Input)
{
act6PID.SetControllerDirection(DIRECT);
analogWrite(13, LOW);
pin=12;
}
else
{
act6PID.SetControllerDirection(REVERSE);
analogWrite(12, LOW);
pin=13;
}
gap = abs(Setpoint-Input); //distance away from setpoint
if(gap<6)
{ //we're close to setpoint, use conservative tuning parameters
act6PID.SetTunings(consKp, consKi, consKd);
}
else
{
//we're far from setpoint, use aggressive tuning parameters
act6PID.SetTunings(aggKp, aggKi, aggKd);
}

act6PID.Compute();
if (gap<2)
{
Output6=0;
}
analogWrite(pin, Output6);
}
count=1;
}

It might be worth having a look at FlightGear. It is open source and will run on Windows, MAC, and Linux.

Russell.

Id second FlighGear. As an open source project all the source code is available to you.
A couple years ago i was investigating receiving data using Telnet/Tcp protocols and was quite succesful.
Alex