Varribas-tfm/quadrotor plugin 2.0
A better plugin for Gazebo
Here you are a brief description of created architecture and features.
You can also see project evolve, motivations and previous implementation here: review_quadrotor_plugin
- Single plugin model
Just declare a single plugin that makes it all possible. No more needed to overload sdf with extra plugins nor extra threads.
- Single Ice Adapter approach
It benefits from single port allocation. Now all Ice interfaces are attached to same port. This simplifies port assignment and mapping (just one for each robot, instead several that jou must tweak for each instance).
Meet conversation here: JdeRobot#199
- Ice PORT can be defined with robot name
Mayor drawback of previous plugin was that it do not allows multiple instances of same robot easy. You must copy all robot config files and change several values!
With this approach, we can do it as better as possible.
We passed from:
- Clone robot model and tweak it (a gazebo model for each instance!)
- Clone Ice config and change ports (a Ice config for each instance!)
- Tweak robot name at world level
- Robot model (sdf) is shared
- Ice config is shared
<?xml version="1.0" ?> <sdf version="1.4"> <world name="default"> <!-- Ground --> <include> <uri>model://ground_plane</uri> </include> <!-- My robots --> <include> <name>quadrotor2-9901</name> <uri>model://ArDrone2</uri> <pose>0 0 0.5 0 0 0</pose> </include> <include> <name>quadrotor2-9902</name> <uri>model://ArDrone2</uri> <pose>1 0 0.5 0 0 0</pose> </include> <include> <name>quadrotor2-9903</name> <uri>model://ArDrone2</uri> <pose>0 1 2 0 0 0</pose> </include> <!-- A global light source --> <include> <uri>model://sun</uri> </include> </world> </sdf>
- Uses native events to feed Ice Interfaces
This feature is hard to explain without explain how it was overcome before:
Each plugin has its own Ice scope, with its own thread for gathering purposes. What this means:
- A event function that receives sensor updates and copy data to a "shared" variable
- A thread (above) that spin forever and take previous staged data and "push" it in Ice interface.
- original data passed by gazebo events or scoped by sensor
- intermediate data that copies out sensor allocated data (critical region)
- cache data that is served to each Ice request (critical region)
Now step (2) is dropped. So by using native events, we can gather sensor information and push/publish to Ice interface. As simple as it sounds!
Without dedicated threads that require self manage lifecycles and so on.
- Ice shutdown
Now Ice Connector lifecycle is correctly managed and implemented with a worse case scenario to ensure that resources are released.
It responds to two hooks:
- Gazebo shutdown
- SIG_INT (a.k.a Ctrl+C)
- Constant velocity takeoff/land
Now you can order land and it will land sightly instead fall down like a rock.
Drawback: if quadcopter was too hight, it will take a long time to reach ground. Just like real ones but without battery drain ;)
- Ad-hoc solution
Use this approach to other robot implies redo it from scratch.
Why? because most code is setup for gazebo and only aliases and helper functions will be meaningful.
Rest is related to quadrotor control and Ice interfaces. These ones could be outsourced to "push" based interfaces.
This simply means that chosen approach is like a pattern, not like a core library.
Bellow image shows briefly how quadrotor architecture is defined and how it is working.
Since quadrotor is a very special case on camera handling (original hardware has camera bandwidth limitation and only one camera can be served), I invest all learned lessons to make a generic architecture to overcome it.
As logical, using native Gazebo's events to keep it simple.
Effort was much more than expected because a JdeRobot's core limitation: it has not any CameraI implementation that includes generic design considerations, so mainly there are a lot of deprecated and partial implementations that do not worth at all.
How to use it
Compile jdeRobot with following options:
[-Dbuild-default=OFF] -Dbuild_gazeboserver=ON -Dbuild_quadrotor2=ON
Spawn as many quadrotors as you want by adding these lines to a world:
<include> <name>quadrotor2-9903</name> <!-- Ice port injection ;) --> <uri>model://ArDrone2</uri> <!-- The model, of course! --> <pose>0 1 2 0 0 0</pose> <!-- Where place it --> </include>
Ice.Config for client side: