User Tools

Site Tools


[[FAQ]] [[Tutorials]] [[Topics]]


-- This tutorial assumes that you are familiar with the [[creating_a_robot|robot]] and [[creating_a_controller|controller]] tutorial -- Now we are going to put together the differential robot, with the controller on an environment to finally have our first simulation running. To create a simulation you have to follow this steps: * Set environment parameters (camera position, gravity, etc.) * Add agents to the scene that consist of a robot, a controller and wiring. * Optionally, add obstacles to the scene. The file where you store you simulation should be called //main.cpp//. This is how a basic simulation looks like: <code c++> // Simulation #include <ode_robots/simulation.h> using namespace lpzrobots; class ThisSim : public Simulation { public: ThisSim() { } ~ThisSim() { } /// start() is called at the start and should create all the object (obstacles, agents...). virtual void start(const OdeHandle& odeHandle, const OsgHandle& osgHandle, GlobalData& global { } /* Functions not used in this tutorial but typically useful */ virtual void addCallback(GlobalData& globalData, bool draw, bool pause, bool control) { } virtual bool command (const OdeHandle&, const OsgHandle&, GlobalData& globalData, int key, bool down) { return false; } virtual void bindingDescription(osg::ApplicationUsage & au) const { } }; int main (int argc, char **argv) { } </code> When the program runs, it will be calling the //main()// function, here you start a new simulation and can set some variable like the caption in the scene. It has to call the //run()// function to start the simulation loop: <code c++> int main (int argc, char **argv) { // New simulation ThisSim sim; // set Title of simulation sim.setTitle("BASIC SIM by Simon"); // Simulation begins return, argv) ? 0 : 1; } </code> The //start()// function will be called by the simulator, and here is where you setup the several parts of a simulation. Lets start with the environment setting. First, we set the camera initial position. We need the actual position of the camera and the pointing direction of it. <code c++> setCameraHomePos(Pos(-14,14, 10), Pos(-135, -24, 0)); </code> The first parameter is the position and the second one is the pointing direction. In order to find suitable parameter, once the simulation is running you can modify the position of the camera with the mouse (using mouse buttons as well) and print the actual position of it by pressing 'p' in the graphical window. We will use this coordinates for now. You can set global parameters of the simulation here. First, the 'controlinterval' will set how often the controller //step()// function is called. A value of 1 means that every simulation step the controller is called. By default the simulation runs 100 times a second. This may be changed with 'simstepsize' if you wish. You can set the gravity as well, try different values. <code c++> global.odeConfig.setParam("controlinterval", 1); global.odeConfig.setParam("gravity", -9.8); </code> For a list of parameters look at the console, they are printed after you start the simulation or check [[classlpz>OdeConfig]]. Next step is to add an agent to the scene. The first step is to add a robot. First we include our differential robot: <code c++> #include "differential.h" </code> Then we get a default configuration of the robot: <code c++> DifferentialConf conf = Differential::getDefaultConf(); </code> At this point we can make local changes to the configuration, for example change the mass of the wheel: <code c++> conf.wheelMass = .5; </code> We instantiate the robot with the actual configuration: <code c++> auto robot = new Differential(odeHandle, osgHandle, conf, "Differential robot"); </code> Here we can also add additional sensors to the robot. This is not required for this simulation but we can still do it, e.g. to record the speed of the robot. <code c++> // add a speed sensor to the robot (attached to the "main primitive" (-1) // (specifiy index if needed) robot->addSensor(std::make_shared<SpeedSensor>(1), Attachment(-1)); </code> The last step for the robot is to set the placement. If we wanted in the middle of the scene we would set every axis to 0, but later we will add a ground with height 0.2, that is why we place the object above that height initially: <code c++> robot->place(Pos(.0, .0, .2)); </code> Next step for the agent is to add a controller, first we include our basic controller: <code c++> #include "basiccontroller.h" </code> and we instantiate it: <code c++> auto controller = new BasicController("Basic Controller"); </code> Next step is a wiring that will connect the robot to the controller, we will add some noise to the channels to simulate real life noise. Therefore, we include the wiring and the noise generator: <code c++> #include <selforg/noisegenerator.h> #include <selforg/one2onewiring.h> </code> And then we instantiate the wiring: <code c++> auto wiring = new One2OneWiring(new ColorUniformNoise(.1)); </code> The wiring connects the robot to the controller. There are different wirings that process the sensor/motor values in one way or the other. The //One2OneWiring// we use here does nothing but adding noise. The final step for the agent is to bind the robot, controller and wiring together, lets include it: <code c++> #include <ode_robots/odeagent.h> </code> We instantiate the agent with the global configurations, then we init it with the three objects and at the end we add it to the agents and configurable list. The latter makes it possible to change parameters of the robot from the command-line. <code c++> auto agent = new OdeAgent(global); agent->init(controller, robot, wiring); global.agents.push_back(agent); global.configs.push_back(agent); </code> Finally, we will add a small arena that is basically a room that the robot will be able to navigate. We will add the simplest one with just four walls which is called playground. The playground will receive a vector with three parameter defining the size of the ground, the width of the wall and the height of the wall: <code c++> osg::Vec3(15., .2, 1.2) </code> The last parameter is the ratio between the sides of the ground, 1 will create a square, a bigger number will create a rectangle. <code c++> auto playground = new Playground(odeHandle, osgHandle, osg::Vec3(15., .2, 1.2), 1.); </code> We can set the colour of the ground defining the RGB colours normalised to [-1,1] range. For the wall colour we also define a transparency value. <code c++> playground->setGroundColor(Color(.784, .784, .0)); playground->setColor(Color(1., .784, .082, .3)); </code> We set the position of the playground and we add it to the list of obstacles: <code c++> playground->setPosition(osg::Vec3(.0, .0, .1)); global.obstacles.push_back(playground); </code> Finally the //start()// function looks like this: <code c++> /// start() is called at the start and should create all the object (obstacles, agents...). virtual void start(const OdeHandle& odeHandle, const OsgHandle& osgHandle, GlobalData& global) { // Initial position and orientation of the camera (use 'p' in graphical window to find out) setCameraHomePos(Pos(-14,14, 10), Pos(-135, -24, 0)); // Some simulation parameters can be set here global.odeConfig.setParam("controlinterval", 1); global.odeConfig.setParam("gravity", -9.8); /** New robot instance */ // Get the default configuration of the robot DifferentialConf conf = Differential::getDefaultConf(); // Values can be modified locally conf.wheelMass = .5; // Instantiating the robot auto robot = new Differential(odeHandle, osgHandle, conf, "Differential robot"); // add a speed sensor to the robot (attached to the "main primitive" (-1) // (specifiy index if needed) robot->addSensor(std::make_shared<SpeedSensor>(1), Attachment(-1)); // Placing the robot in the scene robot->place(Pos(.0, .0, .2)); // Instantiatign the controller auto controller = new BasicController("Basic Controller"); // Create the wiring with color noise auto wiring = new One2OneWiring(new ColorUniformNoise(.1)); // Create Agent auto agent = new OdeAgent(global); // Agent initialisation agent->init(controller, robot, wiring); // Adding the agent to the agents list global.agents.push_back(agent); global.configs.push_back(agent); /** Environment and obstacles */ // New playground auto playground = new Playground(odeHandle, osgHandle,osg::Vec3(15., .2, 1.2), 1); // Set colours playground->setGroundColor(Color(.784, .784, .0)); playground->setColor(Color(1., .784, .082, .3)); // Set position playground->setPosition(osg::Vec3(.0, .0, .1)); // Adding playground to obstacles list global.obstacles.push_back(playground); // Add a new box obstacle (or use 'o' to drop random obstacles) //auto box = new PassiveBox(odeHandle, osgHandle, osg::Vec3(1., 1., 1.), 2.); //box->setPose(osg::Matrix::translate(-.5, 4., .7)); //global.obstacles.push_back(box); } </code> ====== Compiling and running ====== Before you can compile the simulation you need to add the local headers (the one that you created) to the //Makefile.conf// that you have in every simulation directory. For this simulation we have created a new robot (differential) and a new controller (basiccontroller) that resides in the same directory as the //main.cpp// file: //Makefile.conf//: <code> FILES = main differential basiccontroller </code> **Every time you add a new object that is not present in the library you have to add them to the //Makefile.conf// file and call a //make clean// afterwards.** In order to compile just call //make//: <code> $ make </code> If everything goes OK then you can run the simulation by running: <code> $ ./start </code> ====== Basic use of the simulator ====== Once the simulation is running you should be able to see a robot moving around, inside a room with semi-transparent walls. {{:basic.jpg?200|}} **Changing the speed of the simulation**\\ You can increase the speed of the simulation by pressing '+', and decrease it with '-'. To achieve the maximum speed press '*', to come back to real time speed press '/'. **Moving the camera**\\ While holding the right mouse button or the middle button you can move the position of the camera. To know the actual position of the camera press 'p'. **Changing the camera mode**\\ You can change the behaviour of the camera by selecting different types. By pressing '1' you get default camera, with '2' you get following camera and with '3' TV-camera is enabled. **Adding random obstacles**\\ To add a random object press 'o'. **Selecting different agents**\\ If there is more than one agent you can select them by pressing the function keys 'F1', 'F2', etc. **Moving the selected agent**\\ Hold 'Ctrl' and move the agent by dragging the mouse with the left button. Rotate the agent by holding 'Ctrl' and dragging it with the right button. **Visualising sensors and motor values**\\ By default, the sensors and motors values can be visualised with the GUI logger and the Matrix viz. Press 'Ctrl+g' to enable the GUI logger and 'Ctrl+M' to enable the Matrix viz. **Modifying parameter in the Configurator**\\ Open the configurator with 'Ctrl+c'. Modifiable parameters will be shown. For example the threshold of the robot can be set online. **Using the console**\\ Go to the console and press 'Ctrl+c'. The simulation will pause and you can send one command. After this command is sent the simulation will continue. In order to send another command you have to press 'Ctrl+c' again. **On screen help**\\ Press 'h' in the graphic window.

creating_a_simulation.txt · Last modified: 2014/08/22 10:27 by georg