lib/uav_random_direction.cpp
Go to the documentation of this file.
2 
3 uav_random_direction::uav_random_direction (double altitude) : pos(altitude)
4 {
5  NodeHandle nh;
6 
7  // read parameters
8  nh.param(this_node::getName() + "/margin", margin, 0.5);
9 
10  // init random number generator
11  int seed;
12  nh.param<int>("/rng_seed", seed, 0);
13  if (seed != 0) {
15  }
16  else {
18  }
19 
20  // init service clients
21  area_client = nh.serviceClient<cpswarm_msgs::GetPoints>("area/get_area");
23  clear_sector_client = nh.serviceClient<cpswarm_msgs::GetSector>("obstacle_detection/get_clear_sector");
25 
26  // inititial direction as drone is placed
27  direction = pos.get_yaw();
28 
29  // initialize goal
30  goal = pos.get_pose();
31  select_goal();
32 
33  ROS_INFO("Initial direction %.2f", direction);
34 }
35 
37 {
38  delete rng;
39 }
40 
42 {
43  // update position information
44  spinOnce();
45 
46  // at boundary
47  if (pos.reached()) {
48  if (new_direction() == false)
49  return STATE_ABORTED;
50  if (select_goal() == false)
51  return STATE_ABORTED;
52  }
53 
54  // obstacle in direction of new goal
55  if (pos.occupied(goal)) {
56  ROS_DEBUG("Obstacle ahead!");
57  // change direction
58  if (new_direction() == false)
59  return STATE_ABORTED;
60  if (select_goal() == false)
61  return STATE_ABORTED;
62  }
63 
64  // move to new position
65  pos.move(goal);
66 
67  return STATE_ACTIVE;
68 }
69 
71 {
72  pos.stop();
73 }
74 
76 {
77  // calculate goal
78  cpswarm_msgs::GetPoints area;
79  if (area_client.call(area)){
80  // get area polygon
81  vector<geometry_msgs::Point> coords = area.response.points;
82 
83  // find intersecting point of direction and area boundary
84  for (int i = 0; i < coords.size(); ++i) {
85  geometry_msgs::Point v1;
86  v1.x = goal.position.x - coords[i].x;
87  v1.y = goal.position.y - coords[i].y;
88 
89  geometry_msgs::Point v2;
90  v2.x = coords[(i+1)%coords.size()].x - coords[i].x;
91  v2.y = coords[(i+1)%coords.size()].y - coords[i].y;
92 
93  geometry_msgs::Point v3;
94  v3.x = -sin(direction);
95  v3.y = cos(direction);
96 
97  double dot1 = v1.x*v3.x + v1.y*v3.y;
98  double dot2 = v2.x*v3.x + v2.y*v3.y;
99  double cross = v2.x*v1.y - v1.x*v2.y;
100 
101  double t1 = cross / dot2;
102  double t2 = dot1 / dot2;
103 
104  if (t1 >= 0.0 && t2 >= 0.0 && t2 <= 1.0) {
105  goal.position.x += (t1 - margin) * cos(direction);
106  goal.position.y += (t1 - margin) * sin(direction);
107  return true;
108  }
109  }
110 
111  ROS_ERROR("Failed to compute goal");
112  }
113  else{
114  ROS_ERROR("Failed to get area");
115  }
116 
117  return false;
118 }
119 
121 {
122  // get sector clear of obstacles and other uavs
123  cpswarm_msgs::GetSector clear;
124  if (clear_sector_client.call(clear) == false){
125  ROS_ERROR("Failed to get clear sector");
126  return false;
127  }
128 
129  ROS_DEBUG("Clear [%.2f, %.2f] size %.2f", clear.response.min, clear.response.max, clear.response.max - clear.response.min);
130 
131  // generate random direction until one is found inside of area not occupied by obstacles
132  geometry_msgs::Pose goal;
133  do {
134  direction = rng->uniformReal(clear.response.min, clear.response.max);
135  select_goal();
136  ROS_DEBUG_THROTTLE(1, "Checking goal [%.2f, %.2f, %.2f] in direction %.2f...", goal.position.x, goal.position.y, goal.position.z, direction);
137  } while (pos.out_of_bounds(goal));
138 
139  ROS_INFO("Changing direction %.2f", direction);
140 
141  return true;
142 }
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
~uav_random_direction()
Destructor that deletes the private member objects.
bool move(geometry_msgs::Pose pose)
#define ROS_DEBUG_THROTTLE(rate,...)
bool reached()
behavior_state_t
An enumeration for the state of the behavior algorithm.
bool call(MReq &req, MRes &res)
random_numbers::RandomNumberGenerator * rng
The random number generator used for selecting a random direction.
bool occupied(geometry_msgs::Pose pose)
double margin
The distance in meter to keep to the environment boundary.
ServiceClient area_client
Service client to get the area polygon.
position pos
A helper object for position related tasks.
bool select_goal()
Compute goal position from direction.
double get_yaw() const
double direction
The direction in which the drone is travling. It is measured in radian, clockwise starting from north...
geometry_msgs::Pose get_pose() const
bool new_direction()
Compute new direction using rng.
bool waitForExistence(ros::Duration timeout=ros::Duration(-1))
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
uav_random_direction(double altitude)
Constructor that initializes the private member variables.
double uniformReal(double lower_bound, double upper_bound)
behavior_state_t step()
Move the swarm member to a new position.
geometry_msgs::Pose goal
The current goal.
bool out_of_bounds(geometry_msgs::Pose pose)
void stop()
ServiceClient clear_sector_client
Service client for determining the sector clear of obstacles.
ROSCPP_DECL void spinOnce()
#define ROS_ERROR(...)
#define ROS_DEBUG(...)


uav_random_direction
Author(s): Micha Sende
autogenerated on Sat Feb 6 2021 03:11:41