Manual-5
This is the manual for jderobot-5. The most updated release of the documentation for this experimental release is this mediawiki. The API documentation can be found here.
Introduction
What is this Manual for?
This manual is intended to describe the JDErobot 5.0 software, its design and its components. It is oriented to JDErobot users and JDErobot developers. For developers it includes descriptions for each piece of software in this experimental distribution.
This is the official most up to date documentation of JDErobot 5.0. It is written in the mediawiki tool because reading a mediawiki is more handy than reading a manual in paper and because videos can be included, enhancing the descriptions.
What is JDErobot 5.0?
JDErobot 5.0 is a collection of components that communicate between them through ICE. These components use a set of defined interfaces to interact with each other, being this the only coupling mechanism between components. This way we can achieve what we were trying with older versions of JDErobot, a components based architecture, but without the drawbacks of trying to program middleware related code.
JDErobot 5.0 SVN folder organization
Under 5.0 repository, the following folders are available:
- doc/: Access to documentation.
- m4/: Autotools.
- scripts/: Scripts and utilities.
- src/: Source code.
- components/: code for standard components.
- interfaces/: code for standard interfaces.
- libs/: libraries.
- colorspaces/: images and color spaces management.
- jderobotice/: JDErobot library for any topic related to ICE middleware.
- jderobotutil/: JDErobot library for utilities.
Installing JDErobot 5.0
Installing JDErobot 5.0 on Linux Ubuntu 10.04 LTS x86
This is the recommended option for new users. If you previously installed OpenCV in your computer, you must uninstall the libraries, in order to avoid execution problems. The JDErobot 5.0 deb package will install those libraries automatically later.
Installing previous recommended libraries
Some extra libraries are required to compile, link or run JDErobot 5.0. Just type the following "aptitude install" commands:
Basic libraries:
sudo aptitude install build-essential libltdl3 libltdl3-dev libfltk1.1 libfltk1.1-dbg libfltk1.1-dev libtool cmake g++
Xforms libraries:
sudo aptitude install libforms-bin libforms-dev libforms1 libformsgl-dev libformsgl1 libforms-doc
OpenGL libraries:
sudo aptitude install libglut3 libglut3-dev freeglut3 freeglut3-dev glutg3-dev libgl1-mesa-dev libglu1-mesa libglut3 libglut3-dev
GTK libraries:
sudo aptitude install libgtk2.0-0 libgtk2.0-bin libgtk2.0-cil libgtk2.0-common libgtk2.0-dev libgtkgl2.0-1 libgtkgl2.0-dev libgtkglext1 libgtkglext1-dev
Installing JDErobot 5.0 deb package
First of all, we have to remove all these previous packages from your computer, including previous versions of JDErobot.
sudo aptitude remove jderobot jderobot-doc libode1 libode1sp stage libstage2 robot-player libplayerc++2 libplayerc2 libplayercore2
Next, we have to add the JDErobot Apt Repository to the "/etc/apt/sources.list" file:
sudo add-apt-repository "deb http://jderobot.org/apt/ lucid jderobot"
Afterwards, we update the repository cache:
sudo aptitude update
Now we are finally ready to install JDErobot 5.0 on the computer:
sudo aptitude install jderobot
To finish the installation we must add Gearbox library path in the "~/.bashrc" file. So, we have to type this commands on the terminal:
cd -- sudo gedit .bashrc
And add at the end of the file the lines:
# Used in JDErobot 5.0 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/gearbox/
If you're going to compile some own application for JDErobot 5.0, you need to specify where's ICE resources, with a symbolic link:
sudo ln -s /usr/share/Ice-3.3.1/slice /usr/share/slice
Compilling JDErobot 5.0 from source code
This alternative is most appropriate for experienced users.
Installing previous recommended libraries
Some extra libraries are required to compile, link or run JDErobot 5.0. Just type the following "aptitude install" commands:
Basic libraries:
sudo aptitude install build-essential libltdl3 libltdl3-dev libfltk1.1 libfltk1.1-dbg libfltk1.1-dev libtool cmake g++
Xforms libraries:
sudo aptitude install libforms-bin libforms-dev libforms1 libformsgl-dev libformsgl1 libforms-doc
OpenGL libraries:
sudo aptitude install libglut3 libglut3-dev freeglut3 freeglut3-dev glutg3-dev libgl1-mesa-dev libglu1-mesa libglut3 libglut3-dev
GTK libraries:
sudo aptitude install libgtk2.0-0 libgtk2.0-bin libgtk2.0-cil libgtk2.0-common libgtk2.0-dev libgtkgl2.0-1 libgtkgl2.0-dev libgtkglext1 libgtkglext1-dev
Player, Stage, Gazebo
JDErobot-4.3 works fine with these three robotic tools. It may smoothly use Player-2.1.1, Stage-2.1.1 and Gazebo-0.9.
Installing ICE middleware
The new version of JDErobot requieres this GNU component as a feature for communicating different JDErobot components in order to make them work together in a distributed system environment.
ICE, stands for Internet Communications Engine. The software consists of a set of services that allows multiple processes running on one or more machines to interact. It is an object-oriented middleware that provides object-oriented Remote Procedure Call, grid computing and Publish/subscribe functionality developed by ZeroC and dual-licensed under the GNU GPL and a proprietary license. As a high-performance Internet communications platform, Ice includes a wealth of layered services and plug-ins.
Ice is built on concepts which will be familiar to CORBA programmers, and supports a wide variety of programming languages and runtime platforms. Slice is the interface description language used in Ice.
First, ice33-slice component has to be installed (ice*-slice). This package installs the Slice language definitions of standard Ice services on /usr/share/slice. You will find further information in the ZeroC home page (http://www.zeroc.com/ice.html) and in the non-free package zeroc-ice-manual.
$ sudo apt-get install ice33-slice [sudo] password for jvazquez: Reading package lists... Done Building dependency tree Reading state information... Done The following NEW packages will be installed: ice33-slice 0 upgraded, 1 newly installed, 0 to remove and 193 not upgraded. Need to get 181kB of archives. After this operation, 2,966kB of additional disk space will be used. Get:1 http://us.archive.ubuntu.com karmic/universe ice33-slice 3.3.1-6 [181kB] Fetched 181kB in 1s (142kB/s) Selecting previously deselected package ice33-slice. (Reading database ... 176692 files and directories currently installed.) Unpacking ice33-slice (from .../ice33-slice_3.3.1-6_all.deb) ... Setting up ice33-slice (3.3.1-6) ...
At [file:///usr/share/doc/ice33-slice/reference/index.html] directory, a reference guide is available after installation.
It's also neccesary to install ICE translator module, ice33-translators (ice*-translators), by executing the following command:
$ sudo apt-get install ice33-translators Reading package lists... Done Building dependency tree Reading state information... Done The following extra packages will be installed: libiceutil33 libmcpp0 libslice33 The following NEW packages will be installed: ice33-translators libiceutil33 libmcpp0 libslice33 0 upgraded, 4 newly installed, 0 to remove and 193 not upgraded. Need to get 1,440kB of archives. ... Processing triggers for libc-bin ... ldconfig deferred processing now taking place
For a developing environment, it's also requiered the installation of libzeroc-ice33-dev package with any dependency.
$ sudo apt-get install libzeroc-ice33-dev [sudo] password for jvazquez: Reading package lists... Done Building dependency tree Reading state information... Done The following extra packages will be installed: libdb4.6++ libfreeze33 libglacier2-33 libicebox33 libicegrid33 libicepatch2-33 libicessl33 libicestorm33 libicexml33 libzeroc-ice33 libzeroc-ice33-dbg The following NEW packages will be installed: libdb4.6++ libfreeze33 libglacier2-33 libicebox33 libicegrid33 libicepatch2-33 libicessl33 libicestorm33 libicexml33 libzeroc-ice33 libzeroc-ice33-dbg libzeroc-ice33-dev 0 upgraded, 12 newly installed, 0 to remove and 193 not upgraded. Need to get 36.7MB of archives. ... Processing triggers for libc-bin ... ldconfig deferred processing now taking place
Finally, if any ICE service, such us, icegrid or icestorm, is goning to be used, ice33-services (ice*-services) is requiered.
ICE Documentation
You can find an extended on-line manual at http://www.zeroc.com/doc/Ice-3.3.1/manual/toc.html
A simple example with ICE
Hello World (Server & Client C++)
The Interface
First of all, we need to define the ICE interface. In this case the interface is very simple because the application displays a string only.
In the interface we declare the remote functions that will be called by the client and the server. In this way, multiple clients can send multiple requests to be served by a single server or one data can be received by multiple clients.
The code would be:
module Demo {
interface Printer {
void printString(string s);
};
};
The Client
In this case, the client's target is to call the remote function that will write the string that is transferred as input called printString in the interface.
The first step is to declare the variable to communicate:
Ice::CommunicatorPtr ic;
And we must initialize it:
ic = Ice::initialize(argc,argv);
When we have the variable declared and initialized, the next step is to contact with the interfaces; in this example with Printer interface.
We then need to stablish the proxy settings. We can do this in two ways: on the one hand we can use the function "propertyToProxy" to stablish the settings in other file with extension .cfg. Using this way we dont need to change the code if we want to change any property.
On the other hand, we can use the function "stringToProxy" to configurate the proxy with an input string like this example:
Ice::ObjectPrx base = ic->stringToProxy("SimplePrinter:default -p 10000"); // -p xxx -> where xxx is the port to send requests
PrinterPrx printer = PrinterPrx::checkedCast(base); // With the variable casted "printer" we can acces to remote functions.
Finally, we close the connection and show the possibles errors.
catch (const Ice::Exception& ex) {
std::cerr << ex << std::endl;
status = 1;
} catch (const char* msg) {
std::cerr << msg << std::endl;
status = 1;
}
if (ic)
ic->destroy();
The Server
The server is more complex than the client, although we can stablish a standard way to implement it. Remember that the target of the server is to listen on a port for the client requests and, that these requests come through the functions defined in the interface. In this example, the server only shows the text received from the remote function "printString" as seen below:
class PrinterI : public Printer {
public:
virtual void printString(const string& s, const Ice::Current&);
};
Here we declare the class PrinterI which inherits from Printer class generated from printer.ice by the compiler (we will explain this later).
void
PrinterI::printString(const string& s, const Ice::Current&){
cout << s << endl;
}
In this code the printString method is implemented, and we can see that it only shows the string "s", received from the client.
And the main function:
int
main(int argc, char* argv[])
{
int status = 0;
Ice::CommunicatorPtr ic;
As in the client, the variable ic is the communicator which must be initialized:
try {
ic = Ice::initialize(argc, argv);
The next steps are used to specify the server behaviour:
The first step is to create an adapter with a port where is listening the server and a name to identify it:
Ice::ObjectAdapterPtr adapter = ic->createObjectAdapterWithEndpoints("SimplePrinterAdapter", "default -p 10000");
Now, we instantiate our Printer interface by a PrinterI object:
Ice::ObjectPtr object = new PrinterI;
With the "add" function we inform the adapter of the existence of the new object and later we activate it (The server starts processing the incoming requests from clients as soon as the adapter is activated):
adapter->add(object, ic->stringToIdentity("SimplePrinter"));
adapter->activate();
And finally:
ic->waitForShutdown(); } //try
Then, we close the connection and show the possible errors like in the client:
} catch (const Ice::Exception& e) {
cerr << e << endl;
status = 1;
} catch (const char* msg) {
cerr << msg << endl;
status = 1;
}
if (ic) {
try {
ic->destroy();
} catch (const Ice::Exception& e) {
cerr << e << endl;
status = 1;
}
}
Compiling all
THE INTERFACE
The first step is to generate the skeletons and proxies. In order to do this we must compile our Slice definition "Printer.ice" and two files will be generated: the header "Printer.h" (which must be added on the server and the client), and the source file "Printer.cpp". The command line is:
>> slice2cpp Printer.ice
THE SERVER
When the source file is generated, we can compile the server (assuming that the name of the server is "Server.cpp") as follows:
>> c++ -I. -I$ICE_HOME/include -c Printer.cpp Server.cpp
and we need to generate the executable linking it:
>> c++ -o server Printer.o Server.o -L$ICE_HOME/lib -lIce -lIceUtil
Remember that ICE_HOME is the place where you installed Ice 3.3.1 on your computer.
THE CLIENT
The steps are similars to the server. First compiling and then linking:
>> c++ -I. -I$ICE_HOME/include -c Printer.cpp Client.cpp >> c++ -o client Printer.o Client.o -L$ICE_HOME/lib -lIce -lIceUtil
Finally to run both (client and server) we must first start the server in a terminal:
>> ./server
and the client in another terminal:
>>./client
Installing GStreamer development framework
GStreamer is a streaming media framework, based on graphs of filters which operate on media data. Applications using this library can do anything from real-time sound processing to playing videos, and just about anything else media-related. Its plugin-based architecture means that new data types or processing capabilities can be added simply by installing new plug-ins.
This framework is used for Camera component interface impletentations. JDErobot 5.0 Components, such us cameraserver requieres this libraries and development packages.
First, install libgstreamer0.10-dev package for developing environment.
>$ sudo apt-get install libgstreamer0.10-dev Reading package lists... Done Building dependency tree Reading state information... Done The following packages were automatically installed and are no longer required: libsigc++-2.0-dev libxml++2.6-dev libgstreamermm-0.10-2 libglibmm-2.4-dev Use 'apt-get autoremove' to remove them. Suggested packages: gstreamer0.10-doc The following NEW packages will be installed: libgstreamer0.10-dev 0 upgraded, 1 newly installed, 0 to remove and 192 not upgraded. Need to get 0B/873kB of archives. After this operation, 4,047kB of additional disk space will be used. Selecting previously deselected package libgstreamer0.10-dev. (Reading database ... 177838 files and directories currently installed.) Unpacking libgstreamer0.10-dev (from .../libgstreamer0.10-dev_0.10.25-2_i386.deb) ... Processing triggers for man-db ... Setting up libgstreamer0.10-dev (0.10.25-2) ...
Then, install libgstreamer-plugins-base0.10-dev as well
>$ sudo apt-get install libgstreamer-plugins-base0.10-dev Reading package lists... Done Building dependency tree Reading state information... Done The following packages were automatically installed and are no longer required: libsigc++-2.0-dev libxml++2.6-dev libgstreamermm-0.10-2 libglibmm-2.4-dev Use 'apt-get autoremove' to remove them. The following NEW packages will be installed: libgstreamer-plugins-base0.10-dev 0 upgraded, 1 newly installed, 0 to remove and 192 not upgraded. Need to get 0B/138kB of archives. After this operation, 1,450kB of additional disk space will be used. Selecting previously deselected package libgstreamer-plugins-base0.10-dev. (Reading database ... 177967 files and directories currently installed.) Unpacking libgstreamer-plugins-base0.10-dev (from .../libgstreamer-plugins-base0.10-dev_0.10.25-2ubuntu1.2_i386.deb) ... Setting up libgstreamer-plugins-base0.10-dev (0.10.25-2ubuntu1.2) ...
Installing GearBox development package
GearBox has to be also installed. At the moment of this documentation, there isn't a Debian package yet. Installation instructions can be read at http://gearbox.sourceforge.net/gbx_doc_getting.html
- Download gearbox source files http://sourceforge.net/projects/gearbox/files/gearbox/9.11/gearbox-9.11.tar.gz/download
- Install CMake software:
sudo apt-get install cmake
- Follow the rest of configuration, compilation and installation steps for Debian/Ubuntu [1]
Include GearBox libraries path to LD_LIBRARY_PATH environment variable. It'll be required for later references during compilation. Type or include to $HOME/.profile, the following line:
echo "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/gearbox/" >> ${HOME}/.profile && . ${HOME}/.profile
When you are compiling gearbox if you have problem with "libboost_python-mt.so" or "libboost_python-mt.a" you can create the next simbolic link:
$ sudo ln -s /usr/lib/libboost_python.so /usr/lib/libboost_python-mt.so $ sudo ln -s /usr/lib/libboost_python.a /usr/lib/libboost_python-mt.a
Installing OpenCV 2.0.0
OpenCV (Open Source Computer Vision) is a library of programming functions for real time computer vision. It is released under a BSD license, it is free for both academic and commercial use. The library has >500 optimized algorithms (see figure below). It is used around the world, has >2M downloads and >40K people in the user group.
Download OpenCV 2.0.0 from this link and http://opencv.willowgarage.com/wiki/InstallGuide in order to install the component on Linux.
Installing Gtkmm 2.4
Gtkmm is a C++ interface for the popular GUI library GTK+. Gtkmm provides a convenient interface for C++ programmers to create graphical user interfaces with GTK+'s flexible OO framework. Highlights include type safe callbacks, widgets extensible using inheritance and over 180 classes that can be freely combined to quickly create complex user interfaces.
Install libgtkmm-2.4-dev Debian package:
sudo apt-get install libgtkmm-2.4-dev
Installing Libglade 2.4
Libglade is a library which enables an application to build its graphical interface from an XML file (generated by Glade) at runtime. libglademm is the C++ wrapper for libglade.
Install libglademm-2.4-dev Debian package:
sudo apt-get install libglademm-2.4-dev
Installing JDErobot 5.0
Finally, after JDErobot 5.0 is downloaded from the svn repository, we must execute the following steps:
cd $JDEproject_dir aclocal autoconf autoheader autoreconf -vfi automake -a ./configure --prefix=$JDErobot_install_dir --disable-component-recordingserver --with-gearbox=/usr/local make sudo make install
Remember that when using --with-gearbox=/usr/local we must set the gearbox path in our computer, and that it can be different from the one indicated above.
When you are compiling JDErobot 5.0, if you have problems with gazebo, you can't omit this component with the flag "--disable-component-gazeboserver"
./configure --prefix=$JDErobot_install_dir --disable-component-recordingserver --with-gearbox=/usr/local --disable-component-gazeboserver
Interfaces
ImageProvider
Camera
RecordingManager
Motors
Laser
Encoders
PTMotors
PTEncoders
Sonars
Drivers
In this section, we will describe the main components distributed with Jderobot 5.0 that provide access to different sensors and actuators. They are also valuable examples for creating new components as well, so we will describe how to use them and how they work.
cameraserver
Cameraserver is a component to serve N cameras, either real or simulated from a video file. It uses gstreamer internally to handle and to process the video sources.
Provided Interfaces
Required Interfaces
Using cameraserver
To use cameraserver we just have to edit the component's configuration to set the video sources and to set the served formats of our cameras. We also have to set the network address where our component will be listening to for new connections or to choose the locator service.
A configuration file example may be like this:
#network configuration CameraSrv.Endpoints=default -h 127.0.0.1 -p 9999 #cameras configuration CameraSrv.NCameras=1 #camera 0 CameraSrv.Camera.0.Name=cameraA CameraSrv.Camera.0.ShortDescription=Camera pluged to /dev/video0 CameraSrv.Camera.0.Uri=v4l2:///dev/video0 CameraSrv.Camera.0.FramerateN=15 CameraSrv.Camera.0.FramerateD=1 CameraSrv.Camera.0.ImageWidth=320 CameraSrv.Camera.0.ImageHeight=240 CameraSrv.Camera.0.Format=RGB888
If you save the previous configuration file in "cameraServer.cfg",to run CameraViewer with this configuration, you have to type in a shell:
$ cameraserver --Ice.Config=$Config_Path/cameraServer.cfg
The first paragraph define the network configuration, that is the address where our server will be listening to request. Next paragraph define the number of cameras our server will provide. And following it, we have the configuration for the cameras. Notice that each camera will have its parameters after the prefix CameraSrv.Camera.X., with X in the interval [0..NCameras). In this example we have only one camera. A camera has several parameters:
- Name: Name use to serve this camera. The interface for this camera will have this name.
- ShortDescription: A short description of this camera taht may be used by the client to retrieve more information about the camera than only a name.
- Uri: String that define the video source.
- FramerateN: Frame rate numerator.
- FramerateD: Frame rate denominator.
- ImageWidth: Size of the served image.
- ImageHeight: Size of the served image.
- Format: A string defining the format of the served image. Cameraserver use libcolorspacesmm to manage the image formats. Currently accepted formats are RGB888 for RGB 24bits and YUY2.
Cameraserver can serve several types of sources. Each of them are named using the parameter uri with a syntax like:
type-of-source://source-descriptor
where type of source can be one of this:
- v4l or v4l2: For V4l and V4l2 cameras respectively. Source descriptor will name the device name, e.g. v4l2:///dev/video0
- file: For video files. Source descriptor will name the file, e.g file:///home/user/file.avi
- http or https: For files located in a web server. Source descriptor will name the remote resource, e.g http://webserver.com/file.avi
- videotest: For a test video signal with pure colors and noise. Source descriptor will name the video test pattern from 0 to 12 (may differ with gstreamer version), e.g videotest://0
- others: Gstreamer support a big variety of urls to name resources as rtsp, cd, dvd, but not all of them have been fully tested yet.
gazeboserver
gazeboserver is a component used to communicate gazebo with the JDErobot platform. It's possible to retrieve information from several sensor devices, such us: laser, encoders, motors, camera, sonar, ptmotors and ptencoders.
On the last version, gazeboserver supports two cameras with their pantilt units (sony vid30 model).
Provided Interfaces
Using gazeboserver
To use gazeboserver we just have to edit the component's configuration to set ICE communication channel plus the video source and its format. As you notice, each gazeboserver has a robotname. You can use several gazeboserver, but you must change robotname and it automatically changes names of available devices for each robot.
A configuration file example may be like this:
#without registry GazeboServer.Endpoints=default -h localhost -p 9999 GazeboServer.ServerId=0 GazeboServer.ClientId=0 GazeboServer.RobotName=robot1 #cameras configuration GazeboServer.NCameras=2 #camera 1 GazeboServer.Camera.0.Name=cameraA GazeboServer.Camera.0.ImageWidth=320 GazeboServer.Camera.0.ImageHeight=240 GazeboServer.Camera.0.Format=RGB8 #camera 2 GazeboServer.Camera.1.Name=cameraB GazeboServer.Camera.1.ImageWidth=320 GazeboServer.Camera.1.ImageHeight=240 GazeboServer.Camera.1.Format=RGB8
The first paragraph define the network configuration, that is the address where our server will be listening to request. Next paragraph define the number of cameras our server will provide. So, this format is open to support several cameras description. It's an great improvement to work with several cameras. And following it, we have the configuration for the cameras. Notice that each camera will have its parameters after the prefix CameraSrv.Camera.X., with X in the interval [0..NCameras). In this example we have two cameras. Refer to cameraserver description, in order to know more about the meaning of each field. Gaseboserver and cameraserver provides the same camera interface and, therefore, use a common configuration format on this file.
Launching gazeboserver
It's easy. You just type:
$cd /usr/local/share/jderobot/conf $gazeboserver --Ice.Config=gazeboserver.cfg
(You remember you should have already launched gazebo with some of this "teaching robotics worlds").
Playerserver
playersever is a component to communicate with player using JDErobot plataform. It's posible to retrieve information from several sensor devices, such us: laser, encoders, motors, etc.
Provided Interfaces
To use playerverser we just have to edit the component's configuration.
A Configuration file example may be like this:
#without registry PlayerServer.Endpoints=default -h localhost -p 9998 #with registry #PlayerServer.Endpoints=default #PlayerServer.AdapterId=PlayerServer1 #Ice.Default.Locator=IceGrid/Locator:tcp -h localhost -p 12000 #Player server configuration PlayerServer.Hostname=localhost PlayerServer.Port=6665 PlayerServer.Initial_position.X=0 #mm PlayerServer.Initial_position.Y=0 #mm PlayerServer.Initial_position.Theta=90 #deg PlayerServer.Laser=1 PlayerServer.Laser.Num_readings=180 PlayerServer.Laser.Readings_per_degree=1 PlayerServer.Sonars=0 PlayerServer.Encoders=1 PlayerServer.Motors=1 PlayerServer.Bumpers=0 PlayerServer.PTMotors=0 PlayerServer.PTEncoders=0
Launching playerserver
It's easy. You just type:
playerserver --Ice.Config=playerserver.cfg
Jdenect
Jdenect component provides the Kinect drivers needed to communicate it with other components of JdeRobot, providing different images (image depth, RGB image and image of the IR), the neck control and cappability of modifying the LED.
This component is not in the official package, but you can find in the SVN. In order to compile it, you need to install the freenect libraries. You can install this libraries using PPA with this commands.
sudo add-apt-repository ppa:arne-alamut/freenect sudo apt-get update sudo adduser YOURNAME video
If you want to check that you have correctly installed them,connect your kinect and execute:
freenect-glview
To run jdenect type in the shell:
jdenect --Ice.Config=jdenect.cfg
A possible configuration file for this component:
#without registry jdenect.Endpoints=default -h 0.0.0.0 -p 9999 jdenect.robot.ip=127.0.0.1 #jdenect.robot.ip=192.168.2.103 jdenect.robot.port=9559 #with registry #jdenect.Endpoints=default #jdenect.AdapterId=jdenect1 #Ice.Default.Locator=IceGrid/Locator:tcp -h localhost -p 12000 #cameras configuration jdenect.NCameras=1 #camera 1 jdenect.CameraRGB.Name=cameraA jdenect.CameraRGB.ImageWidth=640 jdenect.CameraRGB.ImageHeight=480 jdenect.CameraRGB.Format=RGB8 jdenect.CameraRGB.fp=10 jdenect.CameraDEPTH.Name=cameraB jdenect.CameraDEPTH.ImageWidth=640 jdenect.CameraDEPTH.ImageHeight=480 jdenect.CameraDEPTH.Format=RGB8 jdenect.CameraDEPTH.fp=10 #Other components jdenect.CameraRGB=1 jdenect.CameraDEPTH=1 jdenect.MotorsActive=1 jdenect.PTEncodersActive=1 jdenect.PTMotorsActive=1 jdenect.BodyEncodersActive=1 jdenect.BodyMotorsActive=1 jdenect.BodyMovementsActive=1 jdenect.KinectLedsActive=1
Tools
Basic Component
Provided Interfaces
Features
This component is intended to be used by the new students because its structure is very simple and they can put their navigation algorithms on it.
The component is divided in two threads, one of them is the control thread where we can implement the algorithms and execute them. The other is the GUI thread which displays the images taken by the cameras and we can controll the robot with two virtuals joysticks. The cameras can be controlled too.
In the next schema the structure can be seen:
The source file control_class.cpp is divided in a main function where is established the ICE communications, is created the GUI thread and runs the method iterationControl with the student algorithm. For the other hand, the class "control" is implemented on the same file.
As mentioned before, the robot can be teleoperated. The code contained in TeleoperateCamera.cpp and TeleoperateRobot.cpp implement this functions.
Finally, gui.cpp integrates all methods to show the user interfaces.
cameraview
CameraView is a component to view cameras, which are served by the component CameraViewer
A configuration file example may be like this:
Cameraview.Camera.Proxy=cameraA:default -h 127.0.0.1 -p 9999
Save the previous configuration file in "cameraview.cfg". In order to see the camera's image, we must first run CameraServer and then we have to type in another shell:
$ cameraview --Ice.Config=$Config_Path/cameraView.cfg
If you have configured your cameraViewer and cameraServer with correct parameters, you can see a window with the video.
OpencvDemo
This component implements some of the operations provided by openCV library. They are related to image processing filters and feature detection algorithms. The performance of each filter can be modified by adjusting the parameters directly in the GUI. These operations are:
Image Processing-> Gray scale, Color, Sobel and Laplace filters, Multiresolution Pyramid and Convolutions.
Feature Extraction-> Harris Corners, Canny Edge Detector and Hough Transform both for lines and circles.
Movement Detection-> Optical Flow Detector.
You can freely select the filter in the GUI and even to overlap them.
To configure this component, you just have to specify where the images come from in the "opencvdemo.cfg" file. Here, there is a configuration example to load the images of the laptop's webcam (loading the CameraServer component):
Opencvdemo.Camera.Proxy=cameraA:tcp -h 127.0.0.1 -p 9999
Where "127.0.0.1" is the IP address of the device (local IP in the example) and "9999" is the port number that must coincide with the port of the service provider(cameraserver, gazebosever, etc). The component can be executed by using the regular syntax:
./opencvdemo --Ice.Config=opencvdemo.cfg
A demo of the component can be seen in the video below:
ColorTuner
Colortuner is a component of JdeRobot 5.0 implements three diferents image color filter in the next color spaces: RGB, HSV, YUV, base on the previous "ColorTuner" in JdeRobot 4.3.
Colortuner is an application to configure tailored color filters in HSV, RGB, or YUV color spaces. It is use to obtain optimal values of tint and saturation, as well as lighting, in that kind of filters. To perform the different color conversions between spaces we used the conventions appear in wikipedia, (HSV color conversions), and for YUV, (YUV color conversions) . Colortuner has a very simple way to work. We have two displays, in the first one it shows the original image, as the camera capture it, in the other, it shows the filtered image.
Build a filter is an easy task with it clever display, every single color space have the next possibilities:
- Moving the sliders, up and down to set the maximum and minimum values, for example of RED, GREEN and BLUE, to apply the filter. - From an example pixel of the camera image, just click on a colored area of the image, and HSV, RGB or YUV values will configure automatically.
For HSV and YUV color spaces, colortuner includes an interface representing both color spaces:
- Clicking on the vertex of the area, we could modify the color filter.
We can see two screenshot of the GUI :
| colorTuner HSV | colorTuner YUV |
|
|
To configure this component, you just have to specify where the images come from in the "colortuner.cfg" file. Here, there is a configuration example to load the images.
ColorTuner.Camera.Proxy=cameraA:tcp -h 127.0.0.1 -p 9999
For example, you can use (camerasever) to server image from your webCam, the configuration of this component have to match with the IP and the port you configure on colorTuner.
The component can be execute by using the next line:
colorTuner --Ice.Config=colortuner.cfg
Calibrator
this module is very important because it gives the possibility to efficiently calibrate the cameras. If not properly calibrated, they wont be able, for example, to project points in 3D points correctly or whatever. To find the parameter, you must use the calibrator module.
This section will teach how to launch and monitor its operation. The calibration of a camera is to make the world lines fit with the image objects.
The first thing to do is to launch gazebo:
gazebo /usr/local/share/gazebo/worlds/introrob.world
and gazeboserver, which is capable of communicating with gazebo using JdeRobot platform, you can retrieve information from various types of sensors: laser, motor, or in our case we are interested in the cameras.
cd /usr/local/share/jderobot/glade/ gazeboserver --Ice.Config=../conf/gazeboserver.cfg
Once launched these two components, we can launch the calibrator module.
calibrator --Ice.Config=calibrator.cfg
In the file calibrator.cfg you have to point out where the file of the world is, using the paremeter Calibrator.World.File
An example of this file:
Calibrator.Camera.Proxy=cameraB:tcp -h 0.0.0.0 -p 9999 Calibrator.World.File=./config-example/calib-world #Extrinsics, position Calibrator.Config.Position.X=163 Calibrator.Config.Position.Y=115 Calibrator.Config.Position.Z=286 Calibrator.Config.Position.H=1.000000 #Extrinsics, orientation Calibrator.Config.FOAPosition.X=896 Calibrator.Config.FOAPosition.Y=110 Calibrator.Config.FOAPosition.Z=286 Calibrator.Config.FOAPosition.H=1.000000 #Intrinsics Calibrator.Config.Fx=277.0 Calibrator.Config.Fy=277.0 Calibrator.Config.Skew=0.0 Calibrator.Config.U0=120.0 Calibrator.Config.V0=160.0 Calibrator.Config.Columns=320 Calibrator.Config.Rows=240 Calibrator.Config.Roll=0.00
The format of the world-file is:
#comments worldline x1 y1 z1 h1 x2 y2 z2 h2 worldline -5000,000000 2000,000000 0,000000 1,000000 -5000,000000 -2000,000000 0,000000 1,000000 ...
It is very important for the world coordinates to have the same references found at gazebo
Calibrating gazebo World
we must keep in mind that since we are calibrating a gazebo world, the intrinsic parameters of cameras are ideal. Therefore it follows that:
optical center --> <math> (u_0,v_0) = (\frac{height}{2},\frac{width}{2})</math>
focal distance--> <math> f=\frac{height}{2tan(\theta/2)}</math> where <math>\theta=60^{\circ}</math>
skew --> <math>0.0</math>
So we only use this module to calibrate the extrinsic parameters.
Here you can see a snapshot of the new GUI:
| KRT Matrix | Calibrator GUI |
|
|
As you can see in the GUI, you have several options that you can select it in the differents buttons:
- Watch the optical center - Save the parameters in a file compatible with ICE - Load the lines of a world.
When you modify the value of the scrollbar, you can see a widget with the values of the matriz KRT, as shown on the image above.
Here you can see a video:
Visornect
Visonect component can control and show the images given by the jdenect component to control Kinect. The controls are: to see the image in RGB or IR press the RGB / IR; in order to move the Kinect's neck up or down, press the buttons UP or DOWN; and finally, you can change the color of the LED by pressing the appropriate buttons.
To run the component:
visornect --Ice.Config=visornect.cfg
A possible configuration file:
VisorNect.CameraRGBActive = 1 VisorNect.CameraRGB.Proxy = cameraA: tcp-h 127.0.0.1-p 9999 VisorNect.CameraDEPTHActive = 1 VisorNect.CameraDEPTH.Proxy = cameraB: tcp-h 127.0.0.1-p 9999 VisorNect.PTMotorsActive = 1 VisorNect.PTMotors.Proxy = ptmotors1: tcp-h 127.0.0.1-p 9999 VisorNect.KinectLedsActive = 1 VisorNect.KinectLeds.Proxy = kinectleds1: tcp-h 127.0.0.1-p 9999 VisorNect.WorldFile =./lambecom.cfg
Looking at the last line of the configuration file we can see a file with, in this files we can introduce lines to paint a world in 3D. A sample of this file:
cameraINfile 0 worldconfig/camA-in cameraINfile 1 worldconfig/camB-in cameraINfile 2 worldconfig/camC-in cameraINfile 3 worldconfig/camD-in #cameraINfile 4 /users/s.alons/eldercare-config/worldconfig/camE-in cameraINfile 4 worldconfig/camV-in #units:milimeters #lambecom #floor #2 worldline 0 0 0 1 970 0 0 1 worldline 970 0 0 1 970 800 0 1 worldline 970 800 0 1 2630 800 0 1 worldline 2630 800 0 1 2630 0 0 1 ...
Here you can see two snapshots:
| RGB image nad depth image | View in 3D |
|
|
Libs
Progeo
Visionlib
Fuzzylib
Programming a component for JDErobot 5.0
Programming style
JDErobot code is documented using doxygen. You can find more information here.
Adding a new component to the official repository
The first thing we do is download JdeRobot source code as a developer. In the link above you can see the steps to follow to download the source code as a developer.
Secondly you have to create a folder inside the folder src/component/YOURCOMPONENT and add the code for your component in it. Then we must create a file called Makefile.am, this file is needed for compiling all the source code in one step.
An example of this file is:
src/component/YOUCOMPONENT/Makefile.am
if ENABLE_COMPONENT_OPENCVDEMO
bin_PROGRAMS = opencvdemo
endif
opencvdemo_SOURCES = opencvdemo.cpp \
viewer.cpp \
viewer.h
opencvdemo_CPPFLAGS = $ (GTKMM_CPPFLAGS) $ (OPENCV_CPPFLAGS) \
$ (JDEROBOTICE_CPPFLAGS)-DGLADE_DIR = \ "" $ (gladedir) "\"
opencvdemo_LDFLAGS = $ (JDEROBOTICE_LDFLAGS) $ (GTKMM_LDFLAGS) $ (OPENCV_LDFLAGS)
opencvdemo_LDADD = $ (top_srcdir) / src / libs / jderobotice / libJderobotIce.la \
$ (Top_srcdir) / src / libs / jderobotutil / libJderobotUtil.la \
$ (Top_srcdir) / src / libs / colorspaces / libcolorspaces.la \
$ (Top_srcdir) / src / libs / colorspaces / libcolorspacesmm.la \
$ (Top_srcdir) / src / interfaces / cpp / jderobot / libJderobotInterfaces.la
dist_conf_DATA = opencvdemo.cfg
dist_glade_DATA = opencvdemo.glade
Thirdly we need to modify the Makefile.am file, which is in the folder src/component and add the name of the folder created in the previous point in SUBDIRS
An example of this file is:
src/component/Makefile.am
SUBDIRS = bgfglab calibrator cameraserver CameraViewer cameraview_icestorm motiondetection gazeboserver playerserver giraffeclient introrob naooperator teleoperator jdenect visornect opencvdemo colortuner YOURCOMPONENT MAINTAINERCLEANFILES = Makefile.in Makefile
In the root folder JdeRobot source code you have to modify configure.in file and add a two lines, we have to tell you where is the file .m4 and where is the makefile.
configure.in
... m4_include ([m4/component_YOURCOMPONENT.m4]) ...
...
Makefiles dnl # generate components
AC_CONFIG_FILES ([src/components/Makefile \
src / components/YOURCOMPONENT/Makefile \
src / components/CameraViewer/Makefile \
...
and finally create the file component_YOURCOMPONENT.m4 in the folder m4/, this file must have the same name as instructed in the file configure.in
An example of this type of file is:
m4/component_YOURCOMPONENT.m4
dnl # Requirements for component opencvdemo
dnl # gtkmm & opencv
AC_ARG_ENABLE ([component-opencvdemo]
[AS_HELP_STRING ([- disable-component-opencvdemo]
[Disable component opencvdemo compilation])],
[]
[Enable_component_opencvdemo = yes])
AM_CONDITIONAL ([ENABLE_COMPONENT_OPENCVDEMO], [false])
if test "x $ enable_component_opencvdemo"! = Xno; Then
Checking ([**** AC_MSG_NOTICE opencvdemo component requirements:])
ERRORS = ""
if test "x $ with_colorspacesmm" = Xno; Then
ERRORS = "libcolorspacesmm not enabled"
fi
if test "x $ with_gtkmm" = Xno; Then
ERRORS = "$ ERRORS, gtkmm support not found"
fi
if test "x $ with_opencv" = Xno; Then
ERRORS = "$ ERRORS, opencv support not found. Try setting - with-opencv"
fi
if test "$ ERRORS"; Then
AC_MSG_NOTICE ([Errors found opencvdemo checking requirements: $ ERRORS. Component disabled])
AM_CONDITIONAL ([ENABLE_COMPONENT_OPENCVDEMO], [false])
else
AC_MSG_NOTICE ([Component enabled])
ENABLED_COMPONENTS = "$ ENABLED_COMPONENTS opencvdemo"
AM_CONDITIONAL ([ENABLE_COMPONENT_OPENCVDEMO], [true])
fi
fi
Be careful when you add or modify files in the official repository, because you can make the compilation process fails completely. It is advisable that you compile the code before, to check it out and add only the necessary files. Compile Process
if you want or need to know more about compilation process visit this web
Running JDErobot 5.0
Running components
Each component requires an input configuration file with the format:
... ... myComponent.X.Y = Z ... ...
This format is better defined in ICE middleware documentation.
Thus, the component execution syntax is:
$> jdeComponent --Ice.Config=/JDECOMPONENT_PATH/jdeComponent.cfg
Some entries are required, like the ones defining the component address, if we are connecting our components directly or the locator service if we are using IceGrid. And others are optional, that can define the behavior of our component in some cases. Each component have a set of configuration entries to set its specific parts. A common configuration file may be like this:
CameraSrv.Endpoints=default -h 127.0.0.1 -p 9999 #cameras configuration CameraSrv.NCameras=2 #camera 0 CameraSrv.Camera.0.Name=cameraA CameraSrv.Camera.0.ShortDescription=Camera pluged to /dev/video0 CameraSrv.Camera.0.Uri=v4l2:///dev/video0 ... ...
Here we can see the component's name CameraSrv, the number of cameras (CameraSrv.NCameras) and the defined endpoints, that are the network addresses where our component will tie. The syntax to describe an endpoint is explained in the ICE manual. If we are using a locator service we don't need to define an specific address since we won't connect directly to it but with the indirect proxy that the locator will give us. In this case the configuration would be something like this:
CameraSrv.Endpoints=default CameraSrv.AdapterId=CameraSrv1 Ice.Default.Locator=IceGrid/Locator:tcp -h localhost -p 12000 #cameras configuration CameraSrv.NCameras=2 #camera 0 CameraSrv.Camera.0.Name=cameraA CameraSrv.Camera.0.ShortDescription=Camera pluged to /dev/video0 CameraSrv.Camera.0.Uri=v4l2:///dev/video0 ...
In this last case, we have to define an unique AdapterId that will be used to ask to the locator service, since may exists more than one instance of our server.
The rest of the configuration is used by the component implementation, in this case to set the video sources.
Introrob
Introrob is a component to visualize robot sensor information and to control its actuators. It's implemented with a GUI that facilitates the usage of these capabilities. The initial version has been developed for working with gazeboserver component though it's possible to adapt its configuration file to refer to different data signals.
As it was supported the previous version of JDERobot 4.3, to communicate with gazebo using JDErobot platform. It's possible to retrieve information from several sensor devices, such us: laser, encoders, camera, ptencoders and sonar. It's also possible to control robot's behavior by sending control signals to motors and ptmotors.
At initial version, it's assumed gazebo robot just supports one sensor/actuator of each type. But you can modify gazebo world in order to use two cameras, for instance.
Provided Interfaces
Nothing but GUI for introbot user. It's also possible to encapsulate a different navigation code following this line "ADD YOUR CODE HERE" inside "navega.cpp". It's very useful to test different navigation algorithms on different gazebo worlds. See below, more information about how to adaptate navigation logic for automatic mode.
Required Interfaces
Note: All of them are served by gazeboserver although they can be individually redirect to different providers (i.e: camera coming from cameraserver and not from gazeboserver).
Configuring introrob
To use introrob we just have to edit the component's configuration to set the sensor and actuator location.
A configuration file example may be like this. You can find "introrob.cfg" after Jderobot-5 deb package installation in:
/usr/local/share/jderobot/conf/introrob.cfg
Introrob.Motors.Proxy=motors1:tcp -h localhost -p 9999 Introrob.Camera1.Proxy=cameraA:tcp -h localhost -p 9999 Introrob.Camera2.Proxy=cameraB:tcp -h localhost -p 9999 Introrob.Encoders.Proxy=encoders1:tcp -h localhost -p 9999 Introrob.Laser.Proxy=laser1:tcp -h localhost -p 9999 Introrob.PTEncoders1.Proxy=ptencoders1:tcp -h localhost -p 9999 Introrob.PTEncoders2.Proxy=ptencoders1:tcp -h localhost -p 9999 Introrob.PTMotors1.Proxy=ptmotors1:tcp -h localhost -p 9999 Introrob.PTMotors2.Proxy=ptmotors1:tcp -h localhost -p 9999
With the format "Introrob.X.Proxy=Y:Z", it is possible to specify the individual services to be used. X corresponds to sensor or actuator name: Motors, PTMotors, Encoders, PTEncoders, Sonars, Camera, Laser. Y refers to service name (how it has been denominated at ICE interface). The example shows the default name given by gazeboserver. Finally, Z means the network connection path (protocol, IP address and TCP port).
Using introrob
Introrob provides the following interface by default:
On the top of the window, a 3D visualizer is shown for representing robot's world: robot pioneer, map and laser/sonar measurements. We can change the point of view using buttons located below the visualizer.
On the left-bottom side, we find five buttons in order to control the robot movements: linear and angular speed. The stop button changes the value to 0 (stop linear or radial speed).
Finally, camera display is represented on the right-bottom corner.
Introrob has the following classes distribution:
Introrob class is the main class, responsible for communicating with ICE services, open graphical interface and feed it with sensor data, catch menu events and implement a reaction.
View is accountable for any GUI update and manual navigation event catch. It uses DrawArea to represent OpenGL area information.
Navega embeds your own navigation logic. All this logic is located at iteracionControl and iteracionGrafica, inside this class. From this method it's possible to access to any sensor information and save V, W values robot behavior update.
You can use the following methods:
v: velocidad lineal (mm./s.) a comandar al robot this->controller->setV (float v); w: velocidad rotacional (deg./s.) a comandar al robot this->controller->setW (float w); latitude: posición tilt (deg.) a comandar al cuello mecánico longitude: posición pan (deg.) a comandar al cuello mecánico this->controller->setPT1 (float latitude, float longitude); latitude: posición tilt (deg.) a comandar al cuello mecánico longitude: posición pan (deg.) a comandar al cuello mecánico this->controller->setPT2 (float latitude, float longitude); Formato estructura color RGB => color.x = R; color.y = G; color.z B) this->navegacion->pintaSegmento (CvPoint3D32f a, CvPoint3D32f b, CvPoint3D32f color); Calcula la posicion relativa respecto del robot de un punto absoluto. El robot se encuentra en robotx, roboty con orientacion robotheta respecto al sistema de referencia absoluto this->navegacion->absolutas2relativas(CvPoint3D32f in, CvPoint3D32f *out); Calcula la posicion absoluta de un punto expresado en el sistema de coordenadas solidario al robot. El robot se encuentra en robotx, roboty con orientacion robottheta respecto al sistema de referencia absoluto this->navegacion->relativas2absolutas(CvPoint3D32f in, CvPoint3D32f *out); image: vector correspondiente a la imagen this->navegacion->cogerImagen1(unsigned char* image); image: vector correspondiente a la imagen this->navegacion->cogerImagen2(unsigned char* image); Formato estructura myPoint => myPoint.x = X (mm.); myPoint.y = Y (mm.); myPoint.z = Theta (deg.) this->navegacion->cogerPosicion(CvPoint3D32f* myPoint); Return: nº lásers leídos Parámetro laser: vector de distancias (mm.) vertidos por el láser this->navegacion->cogerLaser(std::vector<float>* laser); Parámetro destino: posición canvas OpenGL establecida por usuario mediante botón central del ratón this->navegacion->cogerDestino(CvPoint2D32f* destino);
Running introrob
Introrob uses gazebo as simulation environment, so we first need to launch it with an specific world called "introrob.world".
$gazebo /usr/local/share/gazebo/worlds/introrob.world
Then, we must launch "gazeboserver" component.
$cd /usr/local/share/jderobot/glade/ $gazeboserver --Ice.Config=../conf/gazeboserver.cfg
As you notice, you must be situated on "glade" directory in order to launch any jderobot component. Anyway, the ".cfg" file is usually on "conf" directory, but you can copy or move it when needed.
(You can check every connection is established and all sensors introrob needs are serving. Otherwise, ".cfg" file may be wrong.)
Now, you finally can launch introrob.
$cd /usr/local/share/jderobot/glade/ $introrob --Ice.Config=../conf/introrob.cfg
Controlling two robots in Gazebo
To introduce two robot and gazebo, it has been necessary to look in the syntax of the configuration files from the worlds of gazebo, written in XML.
Here you can see a example of this file with two robots:
<?xml version="1.0"?>
<gazebo:world
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:gazebo="http://playerstage.sourceforge.net/gazebo/xmlschema/#gz"
xmlns:model="http://playerstage.sourceforge.net/gazebo/xmlschema/#model"
xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor"
xmlns:window="http://playerstage.sourceforge.net/gazebo/xmlschema/#window"
xmlns:param="http://playerstage.sourceforge.net/gazebo/xmlschema/#param"
xmlns:body="http://playerstage.sourceforge.net/gazebo/xmlschema/#body"
xmlns:geom="http://playerstage.sourceforge.net/gazebo/xmlschema/#geom"
xmlns:joint="http://playerstage.sourceforge.net/gazebo/xmlschema/#joint"
xmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface"
xmlns:ui="http://playerstage.sourceforge.net/gazebo/xmlschema/#ui"
xmlns:rendering="http://playerstage.sourceforge.net/gazebo/xmlschema/#rendering"
xmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller"
xmlns:physics="http://playerstage.sourceforge.net/gazebo/xmlschema/#physics" >
<verbosity>5</verbosity>
<physics:ode>
<stepTime>0.03</stepTime>
<gravity>0 0 -9.8</gravity>
<cfm>10e-5</cfm>
<erp>0.3</erp>
<updateRate>33.3333</updateRate>
</physics:ode>
<rendering:gui>
<type>fltk</type>
<size>800 600</size>
<updateRate>20</updateRate>
<pos>0 0</pos>
<frames>
<row height="100%">
<camera width="100%">
<xyz>0.35 -0.5 0.43</xyz>
<rpy>0 14 111.5</rpy>
</camera>
</row>
</frames>
</rendering:gui>
<rendering:ogre>
<ambient>0.5 0.5 0.5 0.5</ambient>
<sky>
<material>Gazebo/CloudySky</material>
</sky>
<grid>true</grid>
<maxUpdateRate>10.</maxUpdateRate>
<shadowTechnique>stencilAdditive</shadowTechnique>
<shadows>true</shadows>
</rendering:ogre>
<!-- Ground plane -->
<model:physical name="plane1_model">
<xyz>0 0 0</xyz>
<rpy>0 0 0</rpy>
<static>true</static>
<body:plane name="plane1_body">
<geom:plane name="plane1_geom">
<normal>0 0 1</normal>
<size>2000 2000</size>
<segments>10 10</segments>
<uvTile>100 100</uvTile>
<material>Gazebo/LightWood</material>
</geom:plane>
</body:plane>
</model:physical>
<!-- ///////////////////////////////////////////////////////robot 1 ///////////////////////////////////////////////// -->
<model:physical name="pioneer2dx_robot1">
<xyz>0 0 0.145</xyz>
<rpy>0.0 0.0 0.0</rpy>
<collide>all</collide>
<model:physical name="laser">
<xyz>0 0 0.19</xyz>
<attach>
<parentBody>chassis_body</parentBody>
<myBody>laser_body</myBody>
</attach>
<include embedded="true">
<xi:include href="models/sicklms200.model" />
</include>
</model:physical>
<!-- left camera -->
<model:physical name="sonyvid30_model_cameraA">
<xyz>0.15 0.11 0.09</xyz>
<attach>
<parentBody>chassis_body</parentBody>
<myBody>sonyvid30_body</myBody>
</attach>
<include embedded="true">
<xi:include href="models/sonyvid30.model" />
</include>
</model:physical>
<!-- rigth camera -->
<model:physical name="sonyvid30_model_cameraB">
<xyz>0.15 -0.11 0.09</xyz>
<attach>
<parentBody>chassis_body</parentBody>
<myBody>sonyvid30_body</myBody>
</attach>
<include embedded="true">
<xi:include href="models/sonyvid30.model" />
</include>
</model:physical>
<include embedded="true">
<xi:include href="models/pioneer2dx.model" />
</include>
</model:physical>
<!-- ///////////////////////////////////////////////////////robot 2 ///////////////////////////////////////////////// -->
<model:physical name="pioneer2dx_robot2">
<xyz>2 0 0.145</xyz>
<rpy>0.0 0.0 0.0</rpy>
<collide>all</collide>
<model:physical name="laser">
<xyz>0 0 0.19</xyz>
<attach>
<parentBody>chassis_body</parentBody>
<myBody>laser_body</myBody>
</attach>
<include embedded="true">
<xi:include href="models/sicklms200.model" />
</include>
</model:physical>
<!-- left camera -->
<model:physical name="sonyvid30_model_cameraC">
<xyz>0.15 0.11 0.09</xyz>
<attach>
<parentBody>chassis_body</parentBody>
<myBody>sonyvid30_body</myBody>
</attach>
<include embedded="true">
<xi:include href="models/sonyvid30.model" />
</include>
</model:physical>
<!-- rigth camera -->
<model:physical name="sonyvid30_model_cameraD">
<xyz>0.15 -0.11 0.09</xyz>
<attach>
<parentBody>chassis_body</parentBody>
<myBody>sonyvid30_body</myBody>
</attach>
<include embedded="true">
<xi:include href="models/sonyvid30.model" />
</include>
</model:physical>
<include embedded="true">
<xi:include href="models/pioneer2dx.model" />
</include>
</model:physical>
<!-- ///////////////////////////////////////////////////////light ///////////////////////////////////////////////// -->
<!-- White Directional light -->
<model:renderable name="directional_white">
<xyz>10 0 5</xyz>
<enableGravity>false</enableGravity>
<light>
<type>spot</type>
<spotCone>1000 1000 100</spotCone>
<direction>-0.1 0 -0.9</direction>
<diffuseColor>0.8 0.8 0.8</diffuseColor>
<specularColor>0.1 0.1 0.1</specularColor>
<range>10</range>
<!-- Constant(0-1) Linear(0-1) Quadratic -->
<attenuation>1.0 0.0 0</attenuation>
</light>
</model:renderable>
<!-- White Point light -->
<model:renderable name="point_white">
<xyz>1 1 100</xyz>
<enableGravity>false</enableGravity>
<light>
<type>point</type>
<diffuseColor>0.9 0.9 0.9</diffuseColor>
<specularColor>0.9 0.9 0.9</specularColor>
<range>200</range>
<!-- Constant(0-1) Linear(0-1) Quadratic -->
<attenuation>0.8 0.001 0.0</attenuation>
</light>
</model:renderable>
</gazebo:world>
It is important to know that when you add a new robot we have to rename the robot, the cameras and lighting. In this file the robot is called pioneer2dx_robot1 you can change the name to pioneer2dx_robot2 or whatever you want. The same with the cameras and lighting.
Configuration files
The configuration files to control two robots.
The configuration file for the robot1:
The file for gazeboserver robot1Gazboserver.cfg
#without registry GazeboServer.Endpoints=default -h localhost -p 9999 GazeboServer.ServerId=0 GazeboServer.ClientId=0 GazeboServer.RobotName=robot1 #cameras configuration GazeboServer.NCameras=2 #camera 1 GazeboServer.Camera.0.Name=cameraA GazeboServer.Camera.0.ImageWidth=320 GazeboServer.Camera.0.ImageHeight=240 GazeboServer.Camera.0.Format=RGB8 #camera 2 GazeboServer.Camera.1.Name=cameraB GazeboServer.Camera.1.ImageWidth=320 GazeboServer.Camera.1.ImageHeight=240 GazeboServer.Camera.1.Format=RGB8
The RobotName have to be the same name the robot must have the same name as the configuration file gazebo. The same with the Name of the cameras.
The file for introrob robot1Introrob.cfg :
Introrob.Motors.Proxy=motors1:tcp -h localhost -p 9999 Introrob.Camera1.Proxy=cameraA:tcp -h localhost -p 9999 Introrob.Camera2.Proxy=cameraB:tcp -h localhost -p 9999 Introrob.Encoders.Proxy=encoders1:tcp -h localhost -p 9999 Introrob.Laser.Proxy=laser1:tcp -h localhost -p 9999 Introrob.PTEncoders1.Proxy=ptencoders1:tcp -h localhost -p 9999 Introrob.PTEncoders2.Proxy=ptencoders2:tcp -h localhost -p 9999 Introrob.PTMotors1.Proxy=ptmotors1:tcp -h localhost -p 9999 Introrob.PTMotors2.Proxy=ptmotors2:tcp -h localhost -p 9999
In this file we have to indicate the name of correct cameras.
The configuration file for the robot2:
robot2GazeboServer.cfg
#without registry GazeboServer.Endpoints=default -h localhost -p 9998 GazeboServer.ServerId=0 GazeboServer.ClientId=0 GazeboServer.RobotName=robot2 #cameras configuration GazeboServer.NCameras=2 #camera 1 GazeboServer.Camera.0.Name=cameraC GazeboServer.Camera.0.ImageWidth=320 GazeboServer.Camera.0.ImageHeight=240 GazeboServer.Camera.0.Format=RGB8 #camera 2 GazeboServer.Camera.1.Name=cameraD GazeboServer.Camera.1.ImageWidth=320 GazeboServer.Camera.1.ImageHeight=240 GazeboServer.Camera.1.Format=RGB8
robot2Introrbo.cfg
Introrob.Motors.Proxy=motors1:tcp -h localhost -p 9998 Introrob.Camera1.Proxy=cameraC:tcp -h localhost -p 9998 Introrob.Camera2.Proxy=cameraD:tcp -h localhost -p 9998 Introrob.Encoders.Proxy=encoders1:tcp -h localhost -p 9998 Introrob.Laser.Proxy=laser1:tcp -h localhost -p 9998 Introrob.PTEncoders1.Proxy=ptencoders1:tcp -h localhost -p 9998 Introrob.PTEncoders2.Proxy=ptencoders2:tcp -h localhost -p 9998 Introrob.PTMotors1.Proxy=ptmotors1:tcp -h localhost -p 9998 Introrob.PTMotors2.Proxy=ptmotors2:tcp -h localhost -p 9998
It very importan to indicate other port in the confiration file.
Running
To execute this you have to open 5 terminals. One for gazebo, two for gazeboserver and two others for introrob and control the robots.
Running Gazebo
gazebo gazeboworld.world
Running gazeboserver for the robot1
gazeboserver --Ice.Config=robot1Gazeboserver.cfg
Running gazeboserver for the robot2
gazeboserver --Ice.Config=robot2Gazeboserver.cfg
Running introrob for the robot1
introrob --Ice.Config=robot1Introrob.cfg
Running introrob for the robot2
introrob --Ice.Config=robot2Introrob.cfg
Configurating Player
In order to configurate Player you need to create two configuration files and an image of the world.
The first file may be like this:
# Desc: Player sample configuration file for controlling Stage devices # Author: Richard Vaughan # Date: 1 December 2004 # CVS: $Id: simple.cfg,v 1.30.2.1 2006/07/13 17:59:10 gerkey Exp $ # load the Stage plugin simulation driver driver ( name "stage" provides ["simulation:0" ] plugin "libstageplugin" # load the named file into the simulator worldfile "cheste.world" ) # Create a Stage driver and attach position2d and laser interfaces # to the model "robot1" driver ( name "stage" provides ["position2d:0" "laser:0" "sonar:0"] model "robot1" ) # Present three interfaces on port 6666, connected to the Stage # position model "gort" and its two grippers. driver ( name "stage" provides ["6666:position2d:0" "6666:laser:0" "6666:sonar:0"] model "robot2" )
The other configuration file may look like this:
# Desc: 1 pioneer robot with laser # CVS: $Id: simple.world,v 1.63 2006/03/22 00:22:44 rtv Exp $ # defines Pioneer-like robots include "pioneer.inc" # defines 'map' object used for floorplans include "map.inc" # defines sick laser include "sick.inc" # size of the world in meters size [16 16] # set the resolution of the underlying raytrace model in meters resolution 0.02 # update the screen every 10ms (we need fast update for the stest demo) gui_interval 20 # configure the GUI window window ( size [ 591.000 638.000 ] center [-0.010 -0.040] scale 0.028 ) # load an environment bitmap map ( bitmap "cheste.png" size [16 16] name "cave" ) # create a robot pioneer2dx ( name "robot1" color "red" pose [-6.5 -6.5 45] sick_laser( samples 361 laser_sample_skip 4 ) ) # create a robot pioneer2dx ( name "robot2" color "blue" pose [-6.5 -5.5 45] sick_laser( samples 361 laser_sample_skip 4 ) )
To run player with this configuration just type:
player configurationfile.cfg
Using the real Pioneer robot
Player
First, we need to launch player with the following configuration file:
>> player pioneer.cfg
An example of configuration file: "pionner.cfg"
driver
(
name "p2os"
provides ["odometry:::position2d:0"
"power:0"
"bumper:0"
"sonar:0"
]
port "/dev/ttyUSB0"
)
driver
(
name "urglaser"
provides ["laser:0"]
port "/dev/ttyACM0"
pose [0.0 0.0 0.0]
baud "19200"
min_angle -90.0
max_angle 90.0
alwayson 1
)
Be careful and make sure the USB corresponds to /dev/ACMX or ttyUSBX, where X is a number. With the command "dmesg" we can discover which one applies.
>> dmesg
PlayerServer
Next, we have to launch the playerserver component. This component is able to connect the components created by player and communicate with them.
playerserver playerserver.cfg
An example of configuration file: "playerserver.cfg"
PlayerServer.Endpoints=default -h localhost -p 9998 #Player server configuration PlayerServer.Hostname=localhost PlayerServer.Port=6665 PlayerServer.Initial_position.X=0 #mm PlayerServer.Initial_position.Y=0 #mm PlayerServer.Initial_position.Theta=90 #deg PlayerServer.Laser=1 PlayerServer.Laser.Num_readings=180 PlayerServer.Laser.Readings_per_degree=1 #PlayerServer.Sonars=0 PlayerServer.Encoders=0 PlayerServer.Motors=1 #PlayerServer.Bumpers=0 #PlayerServer.PTMotors=0 #PlayerServer.PTEncoders=0
Moving the Pioneer
Depends on the sensor you have activated or configurated you can modified introrob to move the robot in the same way you can do it with the simulator gazebo.
Using 2 usb cameras
In order to obtain, for example, stereoscopy, you have to obtain images from 2 cameras. If you want to get the images from real cameras, like USB, you will need cameraserver and for example, 2 cameraview componentes running at the same time.
First we will create 2cameraserver.cfg, where we configure the 2 cameras
##without registry CameraSrv.Endpoints=default -h 0.0.0.0 -p 9999 # client/server mode CameraSrv.DefaultMode=1 # publish/subscribe mode #CameraSrv.TopicManager=IceStorm/TopicManager:default -t 5000 -p 10000 ##with registry #CameraSrv.Endpoints=default #CameraSrv.AdapterId=CameraSrv1 #Ice.Default.Locator=IceGrid/Locator:tcp -h localhost -p 12000 #cameras configuration CameraSrv.NCameras=2 #camera 0 CameraSrv.Camera.0.Name=cameraA CameraSrv.Camera.0.ShortDescription=Camera pluged to /dev/video0 CameraSrv.Camera.0.Uri=v4l2:///dev/video0 CameraSrv.Camera.0.FramerateN=15 CameraSrv.Camera.0.FramerateD=1 CameraSrv.Camera.0.ImageWidth=320 CameraSrv.Camera.0.ImageHeight=240 CameraSrv.Camera.0.Format=RGB8 #camera 1 CameraSrv.Camera.1.Name=cameraB CameraSrv.Camera.1.ShortDescription=Camera pluged to /dev/video1 CameraSrv.Camera.1.Uri=v4l2:///dev/video1 CameraSrv.Camera.1.FramerateN=15 CameraSrv.Camera.1.FramerateD=1 CameraSrv.Camera.1.ImageWidth=320 CameraSrv.Camera.1.ImageHeight=240 CameraSrv.Camera.1.Format=RGB8
Now, we need to create 2 cameraview.cfg files, one for cameraA and one for cameraB. First we create cameraA.cfg:
Cameraview.Camera.Proxy=cameraA:tcp -h 127.0.0.1 -p 9999
And then cameraB.cfg:
Cameraview.Camera.Proxy=cameraB:tcp -h 127.0.0.1 -p 9999
Finnally we open a terminal window (Ctrl + Alt + t) and run:
cameraserver --Ice.Config=2cameraserver.cfg
Then we open another tab in the terminal (Ctrl + Shift + t) and run cameraview
cameraview --Ice.Config=cameraA.cfg
And finally in another tab (Ctrl + Shift + t) we run again cameraview:
cameraview --Ice.Config=cameraB.cfg
And that's it. Just remember that we are using 2 USB cameras at 320x240 and 15 frames/sec. If we wanted to modify these valuse, it must be done in the 2cameraserver.cfg file.