Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Version 65 (modified by fvultier, 9 years ago) (diff)

PPS Coding tutorial

Summary and goals

In this tutorial, you will

  • Download the source code and setup a programming environment on your tardis box
  • Compile the code into a working version of the game
  • Add an in-game object to the game and configure it

Since Orxonox is quite a large project, several steps are required to achieve the above.

Preparations

We check out the source and data repository and build for the first time

The ISG created a special directory for you to store Orxonox in. It is in your home directory and is called

<your-username>-extra-0

Put all your orxonox-related files there. This tutorial will do so as well.

  1. Open a Terminal.
    Applications > Accessories > Terminal
    
  2. Go to your extra-home folder:
    cd ~/<your-username>-extra-0
    
    (or create a folder for yourself on the local harddrive if the extra-home folder does not yet exist)
    mkdir /scratch/<your-username> && cd /scratch/<your-username>
    
  3. Create your orxonox directory (if not already existing):
    mkdir orxonox && cd orxonox
    
  4. Now check out the latest revision of the data repository (you will probably be asked for a username and password once):
    svn co http://svn.orxonox.net/game/data/trunk data_extern
    
    4.1 Open a new terminal tab, to work in parallel.
    Press Control + Shift + T.
    
    4.2 Now get the latest revision of the tutorial:
    svn co http://svn.orxonox.net/game/code/branches/tutorial6 tutorial
    
    4.3 Wait for both branches to check out completely.

4.4 While you wait, download and unzip additional dependencies:

wget http://svn.orxonox.net/downloads/tardisDependencies.zip
unzip tardisDependencies.zip
rm tardisDependencies.zip
  1. Prepare to build:
    mkdir build && cd build
    cmake -G"Eclipse CDT4 - Unix Makefiles" -DECLIPSE_CDT4_GENERATE_SOURCE_PROJECT=TRUE ../tutorial 
    
  2. Now build for the first time (may take some time, further builds will be faster):
    make -j4
    
    The -j4 means to create 4 parallel compile processes.
  3. Additionally you can use Eclipse? as IDE to develop (if you don't want to use the console ;)). You can also use KDevelop3? as IDE, though the assistants can help you more with Eclipse.

Start the game for the first time

  1. Enter to the appropriate folder and start the game. You will see a menu popping up, just press the Quickstart button.
    cd ~/<your-username>-extra-0/orxonox/build
    ./run
    

Before you start coding

Before you start coding there's one page? which is extremely useful for the following tasks. You might want to have a look at it.

The task

Our goal is to create a drone in Orxonox that does some kind of autonomous flying. In Orxonox we try our best to separate different kinds of functionality. You will see that this is also the case here. In the case of the drone we want to create, we separate the drone itself (called AutonomousDrone) from the entity that controls the drone (called the AutonomousDroneController) and the thing that gives shape and texture to our drone (basically that is the model). Or put more crudely, the AutonomousDrone is the physical entity, the AutonomousDroneController is its intelligence and the model is its visual representation. This is done for several reasons, the most important being, that with this kind of separation we can have multiple controllers for just one drone, we could also have one controller for multiple types of flying objects. And the behavior of our drone is independent of how it looks like. That makes your code more generic and leads to cleaner code, less dependencies and also less code in general.

The implementation of our drone will happen in three steps:

  • The AutonomousDrone: Core C++ code for the AutonomousDrone class, contains the C++ ↔ XML interface
  • The AutonomousDroneController: Controller C++ code to steer the drone
  • The XML part: An instantiation in the level file

The AutonomousDrone

At first we need to create the drone itself. The drone provides the functionality of physically having a place in the game world (because it's a WorldEntity) and being able to move in it. Also, this is the place where the XML interface functions are defined so that the game knows what to do if an AutonomousDrone is instantiated in a level file, as we will do in the third part of the tutorial.

Note: Do not just copy & paste! Most commands / codelines need to be edited. But that doesn't mean you shouldn't copy & paste, but you should think about whether what you paste should be modified and how.

Otherwise you'll get tons of compiler errors. Be sure to also read the comments labeled with TODO in the code files.

We created for you the skeleton of an autonomous drone. You can find the code in the files src/orxonox/worldentities/AutonomousDrone.{cc|h} and src/orxonox/controllers/AutonomousDroneController.{cc|h} in the trunk folder that you checked out from our repository.

  1. Open the file AutonomousDrone.cc and have a look at the code (the file can be found in src/orxonox/worldentities/).
  2. In order to be able to create an AutonomousDrone object from the XML file just by using the class name, you need to add a call of RegisterClass(Classname) somewhere inside the .cc (global, inside the namespace). This is best done just above the constructor.
    RegisterClass(ClassX);
    

Note: You have to replace ClassX with the appropriate class.

  1. Make sure that each drone object gets registered to the core by adding a call of RegisterObject(Classname) inside the constructor.
    RegisterObject(ClassX);
    

The next part happens inside the XMLPort function. XMLPort allows you to specify how your class can be instantiated (i.e. how an object can be created) purely through XML. This is important when we want to create levels, which in Orxonox are specified in XML files. The AutonomousDrone has two variables called auxiliaryThrust_ and rotationThrust_ defined in the header file (src/orxonox/worldentities/AutonomousDrone.h). To be able to set these variables to values from XML, we need to add some code to the XMLPort function. There is already an example for the primaryThrust_ variable.

  1. Inside XMLPort, add similar calls for auxiliaryThrust_ and rotationThrust_ using the following scheme:
XMLPortParam(Classname, "xml-attribute-name (i.e. variablename)", setFunction, getFunction, xmlelement, mode)

Note: You need to add set- and get-functions for auxiliaryThrust_ and rotationThrust_ inside the AutonomousDrone.h file (have a look at {get/set}PrimaryThrust).

  1. Now you need to add the AutonomousDrone to the build system. Open the file src/orxonox/worldentities/CMakeLists.txt and add AutonomousDrone.cc to the ORXONOX_SRC_FILES. This makes cmake consider the AutonomousDrone.cc file for further builds.

That's it for the AutonomousDrone class.

If you have been having problems, consider the following suggestions, that might help you resolve them.

  • Is the classname that you specified for RegisterClass(Classname) and RegisterObject(Classname) correct? If it is either Classname, ClassX or ClassXY, then it is incorrect, try to think about what it should be. If you can't find the solution ask one of the assistants.
  • Have you created 2 set-functions and 2 get-functions for the two variables auxiliaryThrust_ and rotationThrust_?

The AutonomousDroneController

Now you will finish the AutonomousDroneController which gets called each tick and steers the drone using the functionality of movement in the game world that the drone provides. i.e. the drone's intelligence.

  1. Open the file AutonomousDroneController.cc and look at it (src/orxonox/controllers/).
  2. Have a look at the constructor and make sure nothing is missing (think of the what we did for the AutonomousDrone).
  3. Now look at the tick function. It gets called each time before a new frame is drawn. you can put in some steering code here. If you want you can use some functions provided by Math.h:
    rnd() // Return a random value between 0 and 1
    sin() // Should be clear (also cos)
    // Many other functions (have a look at src/util/Math.h for details)
    
  4. Repeat step 5 (CMakeLists) of the AutonomousDrone for the AutonomousDroneController.

Again if you have been having problems consider the following suggestions:

  • Did you register the object and create a factory for it? If not or you don't know what this means, have a look at steps 2 and 3 of the AutonomousDrone and think about how this applies to the AutonomousDroneController.

The XML Part

As a last step we will include the drone in our level and add the visual part of the drone, the model (and some other stuff, too).

Now that you finished the classes you can recompile the project. This is again done by typing in the console:

make -j3

Afterwards open the level file:

  1. Open tutorial/data/levels/tutorial.oxw.
  2. We want to add a drone to the level now, so put in an entry for it (below the comment that tells you to do so). Look at this example:
    <ClassX variable1="2" string1="blabla" coord1="1,0,0">
    </ClassX>
    

Of course ClassX has to be replaced with the class name of the object you want to create. Additionally the parameters variable1, string1 and coord1 are just examples, they have to be replaced by the appropriate parameters for your drone.

  1. Now add the appropriate entries for the variables you defined in AutonomousDrone.cc. (Have a look at data/levels/templates/spaceshipAssff.oxt for example values of the different thrusts).
  2. As we want our drone to be visible we have to attach a model to it. Add the following code between the above 2 lines:
      <attached>
        <Model scale="10" mesh="drone.mesh"/>
      </attached>
    
    This adds a model with the mesh drone.mesh and the defined textures at the position of our drone object.
  1. Because the physics engine needs a collision shape to work with, we will add the following entry (before </ClassX>):
      <collisionShapes>
        <BoxCollisionShape position="0,0,0" halfExtents="10, 10, 10" />
      </collisionShapes>
    
    This will tell the physics engine what dimensions our drone has (in this case its just a cube).
  2. Now we define the mass and two damping parameters of our drone. Append definitions for the following variables as attributes to your drone. (as in 3.)
    mass = 50
    linearDamping = 0.9
    angularDamping = 0.7
    
    Note: The Drone definition should now look like this:
    <AutonomousDrone primaryThrust="<...>" <...> mass=50 linearDamping=0.9 angularDamping=0.7>
    
  1. The controller would normally be added to the AutonomousDrone in XML, but as we're currently updating the framework, we need to add this outside the AutonomousDrone. Add these two lines below the AutonomousDrone entry above:
    <AutonomousDroneController>
    </AutonomousDroneController>
    

Have a look at your AutonomousDrone

  • Now recompile the code, start the game again and have a look at how your drone behaves.
  • Don't worry if it does not react to your steering commands as expected. Try to modify some things.
  • If you want to do some more things you can try to let the drone fly in circles or helixes.
  • Play around a little bit with the linear/angular-Damping parameters.