Skip to content
This repository has been archived by the owner on Aug 5, 2022. It is now read-only.

Commit

Permalink
Add Shift Avoidance
Browse files Browse the repository at this point in the history
The shift avoidance strategy uses as input a polar histogram representing the
planar distances of the obstacles in the field of view of the vehicle.  If any
obstacle is detected between the vehicle and the taget, the vehicle moves a
certain distance to the left before checking for obstacles again. If the path
is safe, the vehicle continues to the target.

Signed-off-by: Guilherme Campos Camargo <guilherme.campos.camargo@intel.com>
  • Loading branch information
guiccbr committed Sep 29, 2016
1 parent 23f6c92 commit b31bb89
Show file tree
Hide file tree
Showing 10 changed files with 234 additions and 64 deletions.
1 change: 1 addition & 0 deletions .gitmodules
@@ -1,3 +1,4 @@
[submodule "modules/mavlink_vehicles"]
path = modules/mavlink_vehicles
url = https://github.com/01org/mavlink-vehicles
branch = master
8 changes: 7 additions & 1 deletion avoidance/CMakeLists.txt
@@ -1,9 +1,15 @@
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

set (sources
QuadCopterShiftAvoidance.cc
QuadCopterVFFAvoidance.cc
)

add_library(avoidance ${sources})
target_link_libraries(avoidance common ${GAZEBO_libraries} ${LDFLAGS})
target_link_libraries(avoidance
common
vehicles
${GAZEBO_libraries}
${LDFLAGS}
)

125 changes: 125 additions & 0 deletions avoidance/QuadCopterShiftAvoidance.cc
@@ -0,0 +1,125 @@
/*
// Copyright (c) 2016 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/
#include "QuadCopterShiftAvoidance.hh"
#include "vehicles/MavQuadCopter.hh"
#include "common/common.hh"
#include "common/math.hh"
#include "glm/glm.hpp"

#include <chrono>
#include <memory>
#include <vector>
#include <limits>
#include <iostream>

namespace defaults
{
const double safe_distance = 8.0;
const double lowest_altitude = 1.0;
const double detour_wp_angle = M_PI/3.0;
}

void QuadCopterShiftAvoidance::avoid(const std::vector<double> &histogram,
std::shared_ptr<MavQuadCopter> vehicle)
{
Pose vehicle_pose = vehicle->vehicle_pose();

if (!vehicle->mav->is_ready()) {
return;
}

vehicle->mav->set_autorotate_during_mission(true);
vehicle->mav->set_autorotate_during_detour(false);

switch (this->avoidance_state) {
case avoid_state::detouring: {
// The vehicle is detouring. We need to wait for it to finish the
// detour before checking for obstacles again.

if(vehicle->detour_finished()) {
this->avoidance_state = avoid_state::moving;
std::cout << "[avoid] state = moving..." << std::endl;
}

break;
}
case avoid_state::moving: {
// The vehicle is moving to the target. We need to detect if an
// obstacle is found in order to start a detour.

// The histogram does not have valid data. We're blind.
if (histogram.size() == 0) {
break;
}

// Check if the path in front of the vehicle is safe
if (histogram[0] == 0 || histogram[0] > defaults::safe_distance) {
break;
}

// Check if the current mission waypoint is closer than the closest obstacle
if (mavlink_vehicles::math::ground_dist(
vehicle->mav->get_global_position_int(),
vehicle->mav->get_mission_waypoint()) <= histogram[0]) {
break;
}

// Check if we are too close to ground
if (vehicle_pose.pos.z < defaults::lowest_altitude) {
break;
}

// Calculate the lookat vector
glm::dvec3 view_dir =
glm::dvec3(-sin(vehicle_pose.yaw()), cos(vehicle_pose.yaw()), 0);

// Calculate the direction of the detour waypoint (horizontal rotation
// around lookat vector)
glm::dvec3 wp_dir =
glm::dvec3(view_dir.x * cos(defaults::detour_wp_angle) -
view_dir.y * sin(defaults::detour_wp_angle),
view_dir.x * sin(defaults::detour_wp_angle) +
view_dir.y * cos(defaults::detour_wp_angle),
0.0);

// Calculate the global position of the waypoint
Pose wp =
Pose{vehicle_pose.pos + glm::abs(2.0) * glm::normalize(wp_dir),
glm::dquat(0, 0, 0, 0)};

// Send the detour waypoint to the vehicle
vehicle->set_target_pose(wp);

// Update avoidance state
this->avoidance_state = avoid_state::detouring;

// Print info
std::cout << "[avoid] state = detouring..." << std::endl;

std::cout << "[avoid] wp (x, y, z): " << wp.pos.x << ", " << wp.pos.y
<< "," << wp.pos.z << std::endl;

std::cout << "[avoid] vh (x, y, z): " << vehicle_pose.pos.x << ", "
<< vehicle_pose.pos.y << "," << vehicle_pose.pos.z
<< std::endl;

break;
}
}

return;
}

38 changes: 38 additions & 0 deletions avoidance/QuadCopterShiftAvoidance.hh
@@ -0,0 +1,38 @@
/*
// Copyright (c) 2016 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/
#pragma once

#include "common/common.hh"
#include "vehicles/MavQuadCopter.hh"

#include <chrono>
#include <memory>
#include <vector>

class QuadCopterShiftAvoidance
{
public:
void avoid(const std::vector<double> &histogram,
std::shared_ptr<MavQuadCopter> vehicle);

private:
std::chrono::time_point<std::chrono::system_clock> wp_sent_time =
std::chrono::system_clock::from_time_t(0);

enum class avoid_state { moving, detouring };
avoid_state avoidance_state = avoid_state::moving;
};

24 changes: 14 additions & 10 deletions common/math.cc
Expand Up @@ -35,16 +35,20 @@ Pose operator-(const Pose &a, const Pose &b)

void Pose::set_rot(float pitch, float roll, float yaw)
{
double phi, the, psi;

phi = roll / 2.0;
the = pitch / 2.0;
psi = yaw / 2.0;

this->rot.w = cos(phi) * cos(the) * cos(psi) + sin(phi) * sin(the) * sin(psi);
this->rot.x = sin(phi) * cos(the) * cos(psi) - cos(phi) * sin(the) * sin(psi);
this->rot.y = cos(phi) * sin(the) * cos(psi) + sin(phi) * cos(the) * sin(psi);
this->rot.z = cos(phi) * cos(the) * sin(psi) - sin(phi) * sin(the) * cos(psi);
double phi, the, psi;

phi = roll / 2.0;
the = pitch / 2.0;
psi = yaw / 2.0;

this->rot.w =
cos(phi) * cos(the) * cos(psi) + sin(phi) * sin(the) * sin(psi);
this->rot.x =
sin(phi) * cos(the) * cos(psi) - cos(phi) * sin(the) * sin(psi);
this->rot.y =
cos(phi) * sin(the) * cos(psi) + sin(phi) * cos(the) * sin(psi);
this->rot.z =
cos(phi) * cos(the) * sin(psi) - sin(phi) * sin(the) * cos(psi);
}

double Pose::pitch()
Expand Down
32 changes: 21 additions & 11 deletions samples/CMakeLists.txt
Expand Up @@ -3,18 +3,28 @@ cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
add_executable(coav_gcs coav_gcs.cc)
add_executable(test_detector test.cc)

target_link_libraries(coav_gcs common sensors detection avoidance utils vehicles ${GAZEBO_LIBRARIES} ${PROTOBUF_LIBRARIES} ${LDFLAGS})
target_link_libraries(coav_gcs
common
sensors
detection
avoidance
utils
vehicles
${GAZEBO_LIBRARIES}
${PROTOBUF_LIBRARIES}
${LDFLAGS}
)

target_link_libraries(test_detector
common
communication
detection
utils
sensors
vehicles
${GAZEBO_LIBRARIES}
${PROTOBUF_LIBRARIES}
${OPENGL_LIBRARIES}
${GLUT_LIBRARIES}
common
communication
detection
utils
sensors
vehicles
${GAZEBO_LIBRARIES}
${PROTOBUF_LIBRARIES}
${OPENGL_LIBRARIES}
${GLUT_LIBRARIES}
)

18 changes: 10 additions & 8 deletions samples/coav_gcs.cc
Expand Up @@ -23,11 +23,11 @@
#include <memory>
#include <thread>

#include "avoidance/QuadCopterVFFAvoidance.hh"
#include "avoidance/QuadCopterShiftAvoidance.hh"
#include "vehicles/GazeboQuadCopter.hh"
#include "vehicles/MavQuadCopter.hh"
#include "sensors/GazeboRealSenseCamera.hh"
#include "detection/DepthImageObstacleDetector.hh"
#include "detection/DepthImagePolarHistDetector.hh"
#include "common/common.hh"

enum device_type_ { GAZEBO, PHYSICAL, OTHER };
Expand Down Expand Up @@ -134,8 +134,8 @@ int main(int argc, char **argv)
}

std::shared_ptr<DepthCamera> depth_camera;
std::shared_ptr<QuadCopter> vehicle;
std::shared_ptr<DepthImageObstacleDetector> obstacle_detector;
std::shared_ptr<MavQuadCopter> vehicle;
std::shared_ptr<DepthImagePolarHistDetector> obstacle_detector;

// Initialize Sensors
switch (depth_camera_type) {
Expand All @@ -144,12 +144,13 @@ int main(int argc, char **argv)
case GAZEBO:
depth_camera = std::make_shared<GazeboRealSenseCamera>();
std::cout << "[coav] GazeboRealSenseCamera instantiated" << std::endl;
obstacle_detector = std::make_shared<DepthImageObstacleDetector>(depth_camera);
obstacle_detector = std::make_shared<DepthImagePolarHistDetector>(
depth_camera, 180.0 * (atan(depth_camera->get_fov_tan())) / M_PI);
std::cout << "[coav] ObstacleDetector instantiated" << std::endl;
}

// Initialize Avoidance Strategy
auto avoidance = std::make_shared<QuadCopterVFFAvoidance>();
auto avoidance = std::make_shared<QuadCopterShiftAvoidance>();

// Initialize Vehicle
switch (depth_camera_type) {
Expand All @@ -162,9 +163,10 @@ int main(int argc, char **argv)

while (running) {
// Sense
std::vector<Obstacle> obstacles = obstacle_detector->detect();
std::vector<Obstacle> obstacles;
std::vector<double> hist = obstacle_detector->detect();
// Avoid
avoidance->avoid(obstacles, vehicle);
avoidance->avoid(hist, vehicle);
}
}

Binary file modified testbed/eeprom.bin
Binary file not shown.

0 comments on commit b31bb89

Please sign in to comment.