Tutorial mgEngine / CycabTKSimulator


A mgEngine scene can be divided into 3 parts :

  • The data (meshes, materials, textures, etc.)
  • The script(s) to launch the scene
  • The configuration file(s) to indicate to mgengine where to find data end scripts

In our example, we create a main directory containing all the data and scripts, it contains 4 sub-directories :

  • materials : contains the materials (color of object)
  • meshes : contains the 3D meshes of each object
  • scripts : start script to launch the scene
  • conf : contain som configuration files for simulated components

We have to say to mgengine where to find the ressource, to do that, we create a file tutorial.conf and edit it :

[data path]             "/path/to/the/tutorial/"
[material path]         "$(material path);$(data path)materials"
[mesh path]             "$(mesh path);$(data path)meshes"
[texture path]          "$(texture path);$(data path)textures"
[script path]           "$(script path);$(data path)scripts"
[configuration path]    "$(configuration path);$(data path)conf"
[lua path]              "$(lua path);$(data path)scripts/?.lua"
[input config file]     "$(data path)input.conf"

Creation of the scene


To setup the scene, we write a lua program called tutorial.lua located in the script directory. To see the modification online, you can also write the commands directly to the mgEngine console.

First we change the time parameter to use a constant time step (here 10ms) :

-- Configuration of the simulation engine --

For the visualization, we need to add a display viewport, associated with a camera :

require "mgLuaCameraViewport"
require "mgLuaAccurateRenderer"
-- first we create a renderer --
r = mge.AccurateRenderer "renderer"
-- We create a camera and a camera viewport --
cam = mge.Camera "cam"
cam:SetLocalPosition (-20, -2, 3)
cam:SetLocalRotation (69.282, -69.282, -69.282)
cam:SetPerspective ( 40, 4/3, 0.1, 100 )
v = mge.CameraViewport "v"
v:SetViewport (0, 0, 1024, 768)
v:SetRenderSize (1024, 768)
v.Camera = cam
v.Renderer = r

To navigate in the world, it is convenient to attach a controller to the camera :

require "mgLuaPositionController"
-- we configure the camera controller --
cont = mge.PositionController "cont"
cont.Controlled = cam
cont:SetXPosController	"x_trans"
cont:SetYPosController	"y_trans"
cont:SetZPosController	"z_trans"
cont:SetXRotController	"x_rot"
cont:SetYRotController	"y_rot"
cont:SetZRotController	"z_rot"
cont:SetMode "Walk"
cont.TranslationSpeed = 5.000000
cont.RotationSpeed = 1.000000
One can notice that controllers are binded in the input.conf file.


The environment will be composed of a green ground plane and a blue cube. We create two MeshActor named ground and cube and we associate the corresponding meshes :

require "mgLuaMeshActor"
-- initialization of the environment --
ground = mge.MeshActor "ground"
ground:SetMesh "simple_ground.mesh"
cube = mge.MeshActor "cube"
cube:SetMesh "simple_cube.mesh"
-- change the position of the cube :
cube:SetPosition (0, 0, 1)

We can now add a lightsource and enable the shadows :

sun = mge.LightSource "sun"
sun:SetLocalPosition (-10, -10, 100)
sun.CastShadows = true
ground.CastShadows = false
ground.CatchShadows = true
cube.CastShadows = true

The last thing to do is to initialize the physics engine and to put the environment in it :

require "LuaCycabTK"
require "LuaStdPhysicsEngine"
require "LuaCollisionMesh"
-- we start the Physics Engine --
phyEng = cycabtk.StdPhysicsEngine "phyEng"
phyGround = cycabtk.CollisionMesh "phyGround"
phyCube = cycabtk.CollisionMesh "phyCube"
-- we add collision mesh
phyGround:SetMesh "simple_ground.mesh"
phyCube:SetMesh "simple_cube.mesh"
phyGround:SetChildOf "ground"
phyCube:SetChildOf "cube"

Simulated component

Car-like vehicle

In this section we show how to add a simulated vehicle. Create and edit the file tutorial/SimpleVehicle.lua in the script folder. First, we create a class inherited from cycabtk.DynamicCar to specify the vehicle :

require "LuaCycabTK"
require "LuaDynamicGroundVehicle"
require "LuaDynamicCar"
--Definition of class SimpleVehicle
class 'SimpleVehicle' (cycabtk.DynamicCar)
function SimpleVehicle:__init(name)
    cycabtk.DynamicCar.__init(self, name)

Then, we set the vehicle configuration, we add the main meshe, the wheel meshes, we configure the controller and we enable the actor :

--Definition of class SimpleVehicle
class 'SimpleVehicle' (cycabtk.DynamicCar)
function SimpleVehicle:__init(name)
	cycabtk.DynamicCar.__init(self, name)
	self:SetVehicleConfiguration "tutorial/SimpleVehicle.xml"
	---- initialize mesh actors ----
	self.chassis = mge.MeshActor( name..".chassis" )
	self.chassis:SetMesh "tutorial/chassis.mesh"
	self:AttachTo( name..".chassis" )
	self:SetPhysicMesh("tutorial/chassis.mesh", true);
	---- Initialize the wheels ----
	self.wheel0 = mge.MeshActor(name..".wheel0")
	self.wheel0:SetMesh "tutorial/wheel.mesh"
	self:AttachToWheel(0, name..".wheel0")
	self.wheel1 = mge.MeshActor(name..".wheel1")
	self.wheel1:SetMesh "tutorial/wheel.mesh"
	self:AttachToWheel(1, name..".wheel1")
	self.wheel2 = mge.MeshActor(name..".wheel2")
	self.wheel2:SetMesh "tutorial/wheel.mesh"
	self:AttachToWheel(2, name..".wheel2")
	self.wheel3 = mge.MeshActor(name..".wheel3")
	self.wheel3:SetMesh "tutorial/wheel.mesh"
	self:AttachToWheel(3, name..".wheel3")
 	---- configure the controllers ----
	self.SetManualDriving = true
	---- start the Simulated Actors ----

If we want to access data with ROS, we need to add a ROS interface. In the init function, before self:Start(), add :

    --ROS interface
    require "LuaGroundVehicleOdometryRosInterface"
    self.odometry = cycabtk.GroundVehicleOdometryRosInterface(name..".odometry")
    require "LuaInputCycabControllerRosInterface"
    self.controller = cycabtk.InputCycabControllerRosInterface(name..".controller")

To instanciate this class, add the following command int the main lua program :

require "tutorial/SimpleVehicle"

robot = SimpleVehicle "robot"
Lidar simulator

We will now add a LIDAR in front of the vehicle. We create a class Hokuyo in the file tutorial/Hokuyo.lua

<note> We have two version of the simulator : LidarSimulator or LidarSimulatorZBuffer. The first one uses ray-tracing to compute each laser ray distance, and the second uses the GPU Z-Buffer and is much faster but less accurate.</node>

require "LuaCycabTK"
require "LuaLidarSimulator"
require "LuaLidarViewer"
--Definition of class LidarSystem0
class 'Hokuyo' (cycabtk.LidarSimulatorZBuffer)
function Hokuyo:__init(name)
	cycabtk.LidarSimulatorZBuffer.__init(self, name)

in the init function, we configure each lidar parameter :


To enable the lidar (int the init function):


to add a lidar viewer :

-- Set lidar viewer
self.viewer = cycabtk.LidarViewer( name..".viewer" )
self.viewer:AttachTo( name )

The ros interface :

-- Connectors
require "LuaLidarRosInterface"
self.LaserData = cycabtk.LidarRosInterface( name..".LaserData" )
self:AddPostProcessing( name..".LaserData")
Then, we need to intanciate the lidar to the vehicle created before. In the main program, add :
<code lua>
require "tutorial/Hokuyo"
robot.hokuyo = Hokuyo( "robot.hokuyo" )
robot.hokuyo:SetLocalPosition(1., 0., 0.6)
Camera simulator

Now we add a simulated camera, attached to the vehicle. Create a class Camera in the file tutorial/Camera.lua :

require "LuaCycabTK"
require "LuaCameraSimulator"
--Definition of class CameraSystem1
class 'Camera' (cycabtk.CameraSimulator)
function Camera:__init(name)
	cycabtk.CameraSimulator.__init(self, name)

Configure the size and intrinsic parameters (in the init function):

self.config = self:GetConfig() --cycabtk.CameraConfig
self.config.width = 640
self.config.height = 480
self.config.alpha_u = 600.
self.config.alpha_v = 600.
self.config.u0 = self.config.width/2
self.config.v0 = self.config.height/2
self.config.freq = 25.
self.config.far = 1000.

ROS connector:

-- Connectors
require "LuaCameraRosInterface"
self.image = cycabtk.CameraRosInterface( name..".image" )
self:AddPostProcessing( name..".image")

As for other sensors, we need to instanciate the class and to joint it to the robot :

require "tutorial/Camera"
robot.camera = Camera("robot.camera")
robot.camera:SetLocalPosition(1.5, 0.0, 0.)
robot.camera:LocalRotate(0, 0, -90)

By default, the camera image is displayed on top, we can hide it with the command camera.viewport:Hide() or we can change the viewport position and size with :

robot.camera.viewport:SetViewport( 1024-320, 0, 320, 240)

Launch the simulation

We remind you that the whole tutorial is available on the sources.

Run the simulation with the command :

$ rosrun CycabTKSimulator cycabtk_simulator -f tutorial.conf -l scripts/tutorial.lua

You should see something like that :

tuto/tutorial.txt · Last modified: 2020/06/25 21:27 by arias
Recent changes RSS feed Creative Commons License Donate Minima Template by Wikidesign Driven by DokuWiki