|
|
Posted :
8/23/2004 7:45:00 PM
by Matthieu Laban
Category :
Aviation
[This entry has been imported from my old blog, therefore, links and images might now show correctly. Sorry about that]
Well, I haven’t posted here since my Novodex debacle last week ... You are probably wondering (or not) if I succeeded in adapting my physics code to Novodex ... well, it was a total fiasco, to say the least! I have spent two whole days ignoring the world around me, either virtually or in reality ... two everlasting days at the end of which I managed to successfully... rollback to the prior physics engine... What in the world could have happened ? Well, I would have been glad to say that I managed to make the damn aircraft lift off the ground and fly for a few hundred feet like those Wright guys a century ago. However, the only thing I could get is some ‘entity’ unable to taxi to the runway... neat isn't it? I ran into some problems with the ground behavior of the aircraft, and I didn't want to start with the off ground part until the aircraft was able to roll. Basically, what went wrong is that I had to apply a enormous force on the aircraft to make it roll, and as soon as it left the ground (the wheels friction would become non existent) this force was so strong that it threw the aircraft to those #NAN coordinates :-) (Maybe heaven but looks more like hell to me!) I've restarted from scratch a couple times but in vain ... After 48 hours of people coming to me saying "So, has it taken off yet ?", I finally decided to follow my mum's wise but painful advice, rollback... Thanx to VSS :-P the operation only took a couple minutes...
It's now time to think about this ... why would I want to change the most important part of this in the first place ? Well, only because Novodex's Engine is supposed to be better ... but I think even if its better, it certainly does require as many parameter tweakings as ODE. I would like to mention that i'm not criticizing Novodex's SDK, the only one to blame here would be me :-P I believe I will stick with ODE for now, and try to optimize my scenery to keep a constant frame rate so my physics don't get screwed from non fixed time steps.
Since last update, only a few things have changed on the simulator, I have refactored a few classes to make the airport system less hard coded. Some would say less ‘Commando Patterned’ but whatever ;-) Now, the world is loaded in a big xml file containing what will be the default low resolution tiles of the ground, and in directories such as /airports/[airport name] are xml definitions of the airfields, and the sceneries (3D objects …), again as xml. I’ve also implemented the generation of AI Aircrafts. A manager class loads the aircrafts, assigns them a random flight plan, and puts them on a random parking spot. All I need to do now is to make them speak with the control tower … The generation of the taxiways has been improved as well, by removing nearby nodes and replacing them by a single one, this makes the A* path lookup a tiny bit faster.
About the performance issue, i've posted two images (here and here) on my blog. You can see the airport with thirty AI aircrafts randomly placed on parking spots. This brings the total polygon count to over 44000, and the fps counter shows 10 to 14 fps (debug build)... There is still a lot of room for improvement :-P
Happy landings folks !
|
Posted :
8/19/2004 9:16:00 PM
by Matthieu Laban
Category :
Aviation
[This entry has been imported from my old blog, therefore, links and images might now show correctly. Sorry about that]
Je sors d'une période de quelques heures de semi petage de cable, et j'avais envie d'en parler ... Tout a commencé hier soir, ou je me prennais la tête avec des histoire de stabilité dans ODE ... Des mecs sur gamedev proposaient des algorithmes pour updater la physique indépendement de l'affichage ... il y avait trop de trucs dans le genre time0-time1 * (2 * _interval - (last_interval * last_interval) - time1) pour que je puisse rien qu'essayer d'essayer de comprendre ce que ca pouvait bien faire.. J'ai donc demandé à mon ami Mr Mours, quelles étaient les solutions du "Monde du Jeu Video" ! Il m'a donc dirigé vers une lib super cool de chez Novodex qui fonctionne un peu comme toutes les autres, mais bon, apres avoir essayé tokamak et Ode, je n'étais plus à un wrapping pret ... En me reveillant ce matin, j'ai donc joué avec les petites démos du SDK ... bien sympatique, et bien stable. Je me lance donc dans le wrapping de la lib ... 1000 warnings et 2000 erreurs plus tard, je pouvais enfin faire tomber un cube (managé ! ) :-) Je me suis dit ensuite que j'allais commencer à faire ce qui allait être la physique de mon avion, version 2.0 ! Et c'est la que le drâme commence ... je suis allé de bouletisations en bouletisations ... pendant qq heures, à essayer de modifier la vie pour que ce pauvre avion puisse rouler ... En gros, j'aurais mieux fait de coder un truc com ca :
int retry = 0; while(alive) { "Merde, ça marche pas" cherchage ... "Ahhh, mais quel con ... la c bon, pfiou, rhoo le boulet, ca va marcher maintenant !!" build... run... silence... "ah bah non ..." if (retry > retry_anger_limit) GenerateRandomInsult(); retry++; }
Bref, quand on connait le nombre de paramètres en carton qui entrent en jeu dans ces trucs de physique, il y a de quoi se tirer une balle... ou encore de créer un cube la ou on aurait du créer une sphere ... et qu'on s'étonne que ses roues ne roulent pas ... je prends cet exemple au hazard bien sur ;-)
Maintenant ca marche, et je vais donc pouvoir bouletiser des demain matin sur les parametres de vol de l'avion avec Novodex :-)
Happy Landings Folks.
|
Posted :
8/17/2004 8:42:00 PM
by Matthieu Laban
Category :
Aviation
[This entry has been imported from my old blog, therefore, links and images might now show correctly. Sorry about that]
It is not dull at all, at least when coding it anyway ... Yesterday, I have started implementing what will be my ATC Engine, (Air Traffic Control). This part of the simulator is going to be a tough one, and I understand why we haven't had air traffic control in Flight Simulator prior to FS2002 ! It involves AI for simulating both controllers and flying aircrafts, Path Finding, not to mention the coding behind the communications themselves ... and this is just the beginning. I am sure I’m going to choke on a lot of other things along the way!
So far, I have started implementing a communication system, based on frequencies, just like in reality. A frequency in the simulator is represented as a class. An instance represents a frequency value, and all frequencies in a given area are gathered in a FrequencyManager. When an entity (an aircraft, a controller ...) wants to monitor a certain frequency, it just hooks itself up on the MessageReceived event and it will receive the messages from stations calling the Emit() method on that particular frequency ! When this entity is done listening, the event is unregistered and the messages will not be received anymore. For now, this is working for the Atis (Automatic Terminal Information Service), it sends a fake message telling it's Livermore tower, and that the airport is closed to public air traffic ;-) You can of course hear it via Microsoft Speech stuff :-)
I've also started implementing what will be taxiway lines, for AI aircrafts to know where to go when taxiing for take off, or to the parking, but I’ll will talk about this some other day.
I have posted two new screenshots in the gallery, one showing the Windmill object with scripted behavior, and another one on my tests on path finding.
Happy Landings folks! ?>
|
Posted :
8/15/2004 3:07:00 PM
by Matthieu Laban
Category :
Aviation
[This entry has been imported from my old blog, therefore, links and images might now show correctly. Sorry about that]
In my flight simulator adventure, i started implementing a wind system, to simulate the action of winds on the airplane. It was not that different from what I had done so far. I just needed to add the wind force to my angle of attack calculations. In a few hours the system was working, and I could practice my crosswinds landings :-) Something was missing though, a Windsock. It’s that red and white striped thing that pilots use to find out where the wind is coming from, in order to choose the appropriate runway. All I needed was a 3D Model representing a windsock, and a way to set the orientation of the windsock according to the direction of the wind. I could think of two ways to do this. The easy way, or the Cool Fancy .Netty kinda way. The easy way would be to do some kind of check on an object's tag or name, and to hard code the movement. The cool way would be to build a scripting engine that would compile a specific code associated to an object, and execute it. This portion of code would be given some data it can use to do whatever it wants to do (Moving an object, changing its properties ...) To do this, I created an interface, IScript, defining one method : Update(). This method takes three parameters, the current object, a time delta, and the parent scene.
public void Update(HierarchyObject2 Obj, float dt, Scene ParentScene)
To write the code to interact with the world, the UserPropertyBuffer of 3DSMax nodes are used. This is contained in a CData section of an xml document and looks like this for a windsock orientation.
(Warning, non optimized and totally criticizable code snippet)
AircraftScene scene = ParentScene as AircraftScene; Vector3 WindDirection = scene.WindManager.WindDirection; if (WindDirection.Length() == 0) return; WindDirection.Normalize(); Matrix LocalTransformationMatrix = Obj.LocalTransformationMatrix; LocalTransformationMatrix.M31 = WindDirection.X; LocalTransformationMatrix.M32 = WindDirection.Y; LocalTransformationMatrix.M33 = WindDirection.Z; Vector3 NewRight = Vector3.Cross(MatrixUtils.GetUp(Obj.LocalTransformationMatrix), MatrixUtils.GetAt(LocalTransformationMatrix)); LocalTransformationMatrix.M11 = NewRight.X; LocalTransformationMatrix.M12 = NewRight.Y; LocalTransformationMatrix.M13 = NewRight.Z; Obj.LocalTransformationMatrix = LocalTransformationMatrix;
The value of the CData section is then inserted inside the Update method of a class, implementing the IScript interface that is generated and compiled at runtime. Once this class is instantiated, its Update() method is called at each frame, and the orientation of the windsock is updated according to the wind direction :-) It’s just one possibility of this feature, but I think I will come up with many more (P.a.p.i. (Precision Approach Path Indicator), Flash lights, moving vehicles, spinning radar dishes …) Since the script itself is written in C# and can access everything from the engine, the possibilities are endless ! Screenshots:
The windsock and the wind direction updated from the PropertyGrid.
 The code inside 3DStudio Max Oh, I forgot to mention that the aircraft now has working flaps. The fully extended flaps behavior is still a little weird but the aircraft takes off at a slower speed :-) You can check out my gallery for a screenshot of the Flaps.
Update : (08-15-2004) Since this post has been added to the articles section, I find it convenient to add a little more technical details on how the runtime compilation of the script is done. The first thing we need is a host for our piece of code. It consists of a definition of a class, added as resource to the application and looks like this:
using System; using System.Threading; using System.Drawing; using System.ComponentModel; using System.Windows.Forms; using System.Text; using System.IO; using Microsoft.DirectX; using Microsoft.DirectX.DirectInput; using Microsoft.DirectX.Direct3D; using Direct3D=Microsoft.DirectX.Direct3D; using fmodWrapper;
namespace DirectXLib {{ /// /// Summary description for IScript. /// public class Script : IScript {{ public Script() {{ }}
public void Update(HierarchyObject2 Obj, float dt, Scene ParentScene) {{ {0} }} }} }}
You will notice that instead of having single brackets as delimiter, we have two brackets. This is for a simple reason. Have a closer look at the Update method. There is a « {0} » which is a sort of key word for String.Format(). The single brackets then have to be doubled not to be considered as a beginning/end of a keyword. With this, we can easily insert a piece of code inside the update method.
String CompleteClass = String.Format(ClassString, StringFromObjectProperties) ;
After this call, CompleteClass string contains the code of a complete class.
using System; using System.Threading; using System.Drawing; using System.ComponentModel; using System.Windows.Forms; using System.Text; using System.IO; using Microsoft.DirectX; using Microsoft.DirectX.DirectInput; using Microsoft.DirectX.Direct3D; using Direct3D=Microsoft.DirectX.Direct3D; using fmodWrapper;
namespace DirectXLib { /// /// Summary description for IScript. /// public class Script : IScript { public Script() { }
public void Update(HierarchyObject2 Obj, float dt, Scene ParentScene) { Console.WriteLine(« Object Name : {0} », Obj.Name) ; // Portion of code coming from UserProperties of Object. } } }
Now that we have our class, we need to compile the Assembly that will contain this new Type of ours. Enters CSharpCodeProvider. This class provides us with all the features needed to compile our C# code on the fly. Here is the code that will do this:
/// /// /// /// public CompilerParameters GetCompilerParams() { CompilerParameters cscpCompilerParameters ;
cscpCompilerParameters = new CompilerParameters(); cscpCompilerParameters.GenerateInMemory = true; // Generate our assembly in memory System.Collections.Specialized.StringCollection rs = cscpCompilerParameters.ReferencedAssemblies;
// Get the location of all other assemblies that ours reference Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach(Assembly assembly in assemblies) { // Add each assembly cscpCompilerParameters.ReferencedAssemblies.Add(assembly.Location); }
cscpCompilerParameters.ReferencedAssemblies.Add("DirectXLib.dll"); // add ourself
return cscpCompilerParameters; }
private String GenerateSource(String SourceCode) { try { // Load our data from assembly resources byte[] data = FileManager.ReadFileFromResources("DirectXLib.Device.Scripting.ScriptData.cs", Assembly.GetExecutingAssembly());
if (data != null) { return String.Format(System.Text.Encoding.ASCII.GetString(data), SourceCode); } } catch(Exception Ex) { Log.Debug("Error : {0}", Ex.Message); return null; } return null; }
/// /// Creates an instance of our Script Object /// /// /// private IScript CreateInstance(Assembly ResultAssembly) { IScript script = (IScript)ResultAssembly.CreateInstance("DirectXLib.Script", true); return script; }
/// /// /// /// public IScript CreateScript(String ScriptCode) { String CompleteCode = GenerateSource(ScriptCode);
CSharpCodeProvider cscp = new CSharpCodeProvider(); ICodeCompiler csc = cscp.CreateCompiler(); CompilerResults crs = csc.CompileAssemblyFromSource( GetCompilerParams(), CompleteCode); if (crs.Errors.Count == 0) { Log.Debug("No errors"); Assembly ResultAssembly = crs.CompiledAssembly; return CreateInstance(ResultAssembly); } else { Log.Debug("There are errors:"); foreach (System.CodeDom.Compiler.CompilerError err in crs.Errors) { Log.Debug("Line {0} col {1}: {2}", err.Line, err.Column, err.ErrorText); } } return null; }
One last, the FileManager.ReadFileFromResource, that might be handy.
public static byte[] ReadFileFromResources(String Filename, System.Reflection.Assembly assembly) { FileManager Fileman = new FileManager(); Stream s = assembly.GetManifestResourceStream(Filename);
if (s == null) throw new Exception("Cannot find file in resources"); BinaryReader Reader = new BinaryReader(s); return Reader.ReadBytes((int)s.Length); }
With this code, all we have to do, is call CreateScript() with the code chunk contained in the UserProperties of the current object, an it will return an instance of a class implementing IScript. We can then call the Update method of this instance at every frame, and the script will do its business :-)
Happy Landings everyone!
|
Posted :
8/12/2004 10:02:00 AM
by Matthieu Laban
Category :
Aviation
[This entry has been imported from my old blog, therefore, links and images might now show correctly. Sorry about that]
I’m sure many of you readers from Epitech have heard about a component called PropertyGrid.
It's a component that crawls down an object's structure and displays all its properties. (Using Reflection) You can then visualize the values of the properties and you can edit them directly. The cool thing about this is that it actually updates the values inside the object you gave it.
In my pretend simulator, I came to a point where I wanted better flight/ground behavior, and I did not want to recompile the project at each small parameter change, nor build a form with a million edit boxes on it to edit all the possible variables. I then thought of using a property grid to do this. That way, I do not need a specific window, or to recompile the project every time I want to change something in the flight model. I just need to call a function that will set the physics parameters with new values.
Here is what it looks like:

I have the simulator on the left, the property grid with aircraft variables on the right and all those parameters are editable in real time. Those parameters include contacts smoothness, friction, parts weight ... I hope with the help of this, I’ll reach a little more realism in the simulation.
I am glad I didn't code this engine in C++ ;-) Matt.?>
?>
?>
|
Posted :
8/10/2004 6:34:00 PM
by Matthieu Laban
Category :
Aviation
[This entry has been imported from my old blog, therefore, links and images might now show correctly. Sorry about that]
For the past couple of months, I have kept myself busy trying to code my very own flight simulator... This must have been my billionth attempt at doing it, and the previous versions were not big successes to say the least...
This time I have tried a slightly different approach. I've come to the conclusion that my math/physics skills were definitely not high enough to code an acceptable rigid body simulation, aviation wise at least... I've spent countless hours trying to tweak the FlightSim example of the book "Physics for game developers", to come to the conclusion that, even if I have a flyable model, the ground behavior of the aircraft would be even harder to simulate!
I then decided to use one of the few Rigid Body libraries freely available, and I looked into Tokamak and ODE. I chose the later, and I do not really know why, since I believe both would more than satisfy my needs.
I wrote a little .Net wrapper for both Tokamak and ODE prior to make my choice.
(Note to self: refactor this (crappy) ODE Wrapper...)
Now that the wrapper has been written, all i needed to do was to apply forces related to the flight of an aircraft at the appropriate points on the plane.
Luckily, ODE has a set of useful functions for that.
The first interesting one is a function to add a force at a certain position relative to a body. This can be used to apply forces such as Lift, Drag, and Thrust. Of course, these forces are to be added at the position of a wing (lift and drag), or where an engine would be (thrust).
The second one is to get the linear velocity at a certain point of a body. This can be used to calculate the angle of attack of a wing for instance, therefore, its lift and drag, that we can apply at next step to the aircraft parts!
With this, we can basically make an object lift off the ground, with the proper lift/drag calculations related to the aircraft velocity.
(The local velocity of each aircraft part).
This sounds quitestraight forward, but to make a state of the art simulator, the road is long! (Where is that road anyways?! :-P)
The current state of the 'project' is quite satisfying :P I’ve got an aircraft that can take off, turn (not too steep though :D), gain, lose altitude, land, and the ground behavior is... well, it can roll ...
The part that made me choke the most is to have a stable flight when the aircraft is changing its course. Some forces are applied to the rudder (vertical tail wing), in function of the difference between the actual aircraft velocity and the aircraft 'at'. At first i was too lazy to add the forces connected to this particular wing :P but I’ve come to the conclusion that without this wing, the aircraft can't really change its course ... (for real pilots reading, it's when the turn coordinator's ball is really not centered :D)
There is really room for improvement here, especially on the lack of impression of speed, the brutal motion of the aircraft, the stupid rudder that is not doing its job. One other thing to improve would be to use a non-linear lift coefficient. This would add the ability for wings to stall when lift is not sufficient due to a high angle of attack.
I also intend to add some IA aircrafts to fly along as well as ATC traffic, using MS Text To Speech :)
I have posted some screenshots in my gallery.
For a downloadable version, you will have to wait a little more. ?>
|
Posted :
8/7/2004 11:28:00 AM
by Matthieu Laban
Category :
Aviation
[This entry has been imported from my old blog, therefore, links and images might now show correctly. Sorry about that]
Since everyone here is writing about what they like, it is my turn to talk about something I enjoy...
I know this post won't drain a lot of people, but I know there are quite a few flight sim enthusiasts at Epitech J
I recently purchased what i think might be the best scenery ever released for Flight Simulator 2004. It is called "Mega Scenery USA 2004, Northern California" When this new title from Aerosoft/PCAviator was announced, i was really looking forward to order it. Like my fellow flight simmers this scenery reminds me of the good old times, when we were flying Flight unlimited II & III from Looking Glass Studios, which were modeling this area in tremendous details ! Don't look for the official website on the net, it does not exist anymore, Looking Glass closed its doors a few years ago (what a shame :-/)
The point of this post is to tell you how much I enjoy flying over this scenery which is meant to be flown in VFR, and comes with VFR charts of the Area. The scenery extends from a few miles north of Santa Rosa to Monterey, and from the West Coast to Calaveras/Merced CA so there's a lot of airspace, points of interest to explore! (30’000 square miles)
So anyways, don't hesitate to get this scenery, you won't regret it ! :-) While you’re on their website, add MegaScenery USA Southern California to your cart as well, it's also very good ! :) (All LA Area down to San Diego, Santa Catalina, Ontario, Big Bear Lake ...) If you want more information on these sceneries, check out www.megascenery.com
I posted a few screenshots on a gallery of my blog ;-)
Happy Landings! Matt ?>
|
|
|
|