-
Notifications
You must be signed in to change notification settings - Fork 38
TutorialBasic
This is a basic tutorial that demonstrates the basic flow of an app using the library, how to instantiate its components and how to put it all together. This is also the basis for the advanced tutorial on creating custom components.
An app will generally follow the following flow: First it will create a vehicle object that will be responsible for communication with our actual vehicle (real or simulated). Then, it will create a sensor object that represents the vehicle's sensor that should be used for detecting obstacles. With the sensor, it will instantiate the detector, which is responsible for reading and interpreting the sensor data. Finally, the detector result must be forwarded to a avoidance strategy, which will use that data plus the vehicle object to maneuver the vehicle.
- Program Skeleton
- Loading a Vehicle
- Loading a Sensor
- Loading a Detector
- Loading an Avoidance Strategy
- Putting it all Together
- The Final App
TO get started with developing your own app, first you need a base skeleton and a cmake file that will compile it.
NOTE: At this time, the project does not export and/or install a library, so for this tutorial we will add our program to the samples/
folder in the project root and compile it with the rest of the library.
First, let's create a simple skeleton
samples/myapp.cc
#include <iostream>
#include <memory>
#include "common/common.hh"
using namespace std;
int main(int argc, char **argv)
{
cout << "My custom app" << endl;
return 0;
}
The common/common.hh
header has the basic structures of the library and should be present in all apps. The memory
header will be used for managing our object pointers.
Now let's add it to the build system. We will be developing custom sensors, vehicles, detectors and avoidance strategies, so we need to make sure our app is linked against all those libraries. Open up the samples/CMakeLists.txt
file and add the following lines at the end of the file:
samples/CMakeLists.txt
add_executable(myapp myapp.cc)
target_link_libraries(myapp common sensors detection avoidance vehicles)
At this point you should be able to compile and test your new app.
mkdir build/
cd build
cmake WITH_REALSENSE=ON ..
make
./samples/myapp
For multicopters that communicate via Mavlink, the library provides a vehicle class named MavQuadCopter
. For now, that is the vehicle that we are going to use.
First add the appropriate header to myapp.cc:
#include "vehicles/MavQuadCopter.hh"
Then, in the main()
function, instantiate the vehicle:
shared_ptr<MavQuadCopter> vehicle = make_shared<MavQuadCopter>();
If no parameter is provided, the vehicle will use the default port (15557) for connection.
Loading a sensor is similar to loading a vehicle. First we need to add the appropriate header for the sensor. For this tutorial, we will use the Intel RealSense DepthCamera.
#include "common/DepthCamera.hh"
#include "sensors/RealSenseCamera.hh"
NOTE: Make sure to pass WITH_REALSENSE=ON option when configuring the project with cmake.
Now we can initialize the sensor.
shared_ptr<DepthCamera> sensor = make_shared<RealSenseCamera>(640, 480, 30);
This will initialize the RealSense depth sensor to a 640x480 resolution at 30fps.
For this tutorial we will be using the Depth Image Obstacle Detector, which is a detector based on blob identification in the sensor data. For a list of available detectors and their descriptions, check Detectors.
First we add the appropriate header:
#include "detection/DepthImageObstacleDetector.hh"
and then load the detector
shared_ptr<Detector<DepthCamera>> detector = make_shared<DepthImageObstacleDetector>(sensor, 5.0);
The second parameter is the threshold in meters. Any sensor readings above that value will be ignored by this detector.
For this tutorial we will be using the Quadcopter Stop Stop Avoidance strategy. For a list of available avoidance strategies, check Avoidance Strategies
First we add the appropriate header:
#include "avoidance/QuadCopterStopAvoidance.hh"
And then load the detector:
shared_ptr<CollisionAvoidanceStrategy<MavQuadCopter>> avoidance = make_shared<QuadCopterStopAvoidance>(vehicle);
At this point we got all the components that we need to process the sensor data and maneuver the vehicle if an obstacle is detected. The only thing left to do is keep reading the sensor data and feeding it to the avoidance strategy:
while (true) {
avoidance->avoid(detector->detect());
}
Our final app is composed of the CMakeLists.txt change and the myapp.cc file. When it is all done, they will look like:
samples/CMakeLists.txt
add_executable(myapp myapp.cc)
target_link_libraries(myapp common sensors detection avoidance vehicles)
samples/myapp.cc
#include <iostream>
#include <memory>
#include "avoidance/QuadCopterStopAvoidance.hh"
#include "common/common.hh"
#include "common/DepthCamera.hh"
#include "detection/DepthImageObstacleDetector.hh"
#include "sensors/RealSenseCamera.hh"
#include "vehicles/MavQuadCopter.hh"
using namespace std;
int main(int argc, char **argv)
{
cout << "My custom app" << endl;
shared_ptr<MavQuadCopter> vehicle = make_shared<MavQuadCopter>();
shared_ptr<DepthCamera> sensor = make_shared<RealSenseCamera>(640, 480, 30);
shared_ptr<Detector<DepthCamera>> detector = make_shared<DepthImageObstacleDetector>(sensor, 5.0);
shared_ptr<CollisionAvoidanceStrategy<MavQuadCopter>> avoidance = make_shared<QuadCopterStopAvoidance>(vehicle);
while (true) {
avoidance->avoid(detector->detect());
}
return 0;
}