lib/ugv_random_walk.cpp
Go to the documentation of this file.
1 #include "lib/ugv_random_walk.h"
2 
4 {
5  NodeHandle nh;
6 
7  // init random number generator
8  int seed;
9  nh.param<int>("/rng_seed", seed, 0);
10  if (seed != 0) {
11  ROS_INFO("Using seed %d for random number generation.", seed);
13  }
14  else {
16  }
17 
18  // init service clients
19  bound_client = nh.serviceClient<cpswarm_msgs::ClosestBound>("area/closest_bound");
21  clear_sector_client = nh.serviceClient<cpswarm_msgs::GetSector>("obstacle_detection/get_clear_sector");
23 
24  // initial direction as drone is placed
25  direction = pos.get_yaw();
26  ROS_INFO("Initial direction %.2f", direction);
27 
28  // read parameters
29  // get step size from optimized candidate
30  nh.param(this_node::getName() + "/step_size", step_size, 3.0);
31  ROS_INFO("Step size %.2f", step_size);
32 }
33 
35 {
36  delete rng;
37 }
38 
40 {
41  // update position information
42  spinOnce();
43 
44  // compute new goal
45  geometry_msgs::Pose goal = select_goal();
46 
47  // reflect from bound
48  if (pos.out_of_bounds(goal)) {
49  if (reflect() == false)
50  return STATE_ABORTED;
51  goal = select_goal();
52  }
53 
54  // move to new position
55  if (pos.move(goal) == false)
56  return STATE_ABORTED;
57 
58  // change direction
59  if (new_direction() == false)
60  return STATE_ABORTED;
61 
62  // return state to action server
63  return STATE_ACTIVE;
64 }
65 
67 {
68  pos.stop();
69 }
70 
72 {
73  // get sector clear of obstacles and other uavs
74  cpswarm_msgs::GetSector clear;
75  if (clear_sector_client.call(clear) == false){
76  ROS_ERROR("Failed to get clear sector");
77  return false;
78  }
79 
80  ROS_DEBUG("Clear [%.2f, %.2f] size %.2f", clear.response.min, clear.response.max, clear.response.max - clear.response.min);
81 
82  // generate random direction until one is found inside of area not occupied by obstacles
83  geometry_msgs::Pose goal;
84  do {
85  direction = rng->uniformReal(clear.response.min, clear.response.max);
86  goal = select_goal();
87  ROS_DEBUG_THROTTLE(1, "Checking goal [%.2f, %.2f, %.2f] in direction %.2f...", goal.position.x, goal.position.y, goal.position.z, direction);
88  } while (pos.out_of_bounds(goal));
89 
90  ROS_INFO("Changing direction %.2f", direction);
91 
92  return true;
93 }
94 
96 {
97  // get boundary
98  geometry_msgs::Point b1;
99  geometry_msgs::Point b2;
100  cpswarm_msgs::ClosestBound cb;
101  cb.request.point = pos.get_pose().position;
102  if (bound_client.call(cb)){
103  b1 = cb.response.coords[0];
104  b2 = cb.response.coords[1];
105  }
106  else{
107  ROS_ERROR("Failed to get area boundary");
108  return false;
109  }
110 
111  // calculate reflection
112  direction = remainder(-atan2(b2.y - b1.y, b2.x - b1.x) - direction, 2*M_PI);
113 
114  ROS_INFO("Changing direction %.2f", direction);
115 
116  return true;
117 }
118 
119 geometry_msgs::Pose ugv_random_walk::select_goal ()
120 {
121  // compute goal position
123 }
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
behavior_state_t
An enumeration for the state of the behavior algorithm.
bool move(geometry_msgs::Pose pose)
#define ROS_DEBUG_THROTTLE(rate,...)
bool call(MReq &req, MRes &res)
random_numbers::RandomNumberGenerator * rng
The random number generator used for selecting a random direction.
double get_yaw() const
geometry_msgs::Pose get_pose() const
ServiceClient bound_client
Service client for determining closest mission area boundary to the current UGV position.
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
bool reflect()
Compute new direction as reflection from wall.
double step_size
The distance that the UGV travels in one step.
bool new_direction()
Compute new direction using rng.
double uniformReal(double lower_bound, double upper_bound)
geometry_msgs::Pose compute_goal(double distance, double direction) const
behavior_state_t step()
Move the swarm member to a new position.
ugv_random_walk()
Constructor that initializes the private member variables.
position pos
A helper object for position related tasks.
~ugv_random_walk()
Destructor that deletes the private member objects.
bool out_of_bounds(geometry_msgs::Pose pose)
void stop()
void stop()
Stop moving.
ServiceClient clear_sector_client
Service client for determining the sector clear of obstacles.
geometry_msgs::Pose select_goal()
Compute goal position from direction.
ROSCPP_DECL void spinOnce()
#define ROS_ERROR(...)
double direction
The direction in which the UGV is traveling. It is measured in radian, clockwise starting from north...
#define ROS_DEBUG(...)


ugv_random_walk
Author(s): Micha Sende
autogenerated on Sat Feb 6 2021 03:11:46