Fields2CoverVisualizerNode.cpp
Go to the documentation of this file.
1 //=============================================================================
2 // Copyright (C) 2021-2022 Wageningen University - All Rights Reserved
3 // Author: Gonzalo Mier
4 // BSD-3 License
5 //=============================================================================
6 
7 
9 #include "ros/conversor.h"
10 
11 #include <fstream>
12 #include <iostream>
13 #include <dynamic_reconfigure/server.h>
14 #include <fields2cover_ros/F2CConfig.h>
15 
16 
17 using namespace std;
18 
19 
20 namespace fields2cover_ros {
21 
22  void VisualizerNode::init_VisualizerNode() {
23  field_polygon_publisher_ = public_node_handle_.advertise<geometry_msgs::PolygonStamped>("/field/border", 1, true);
24  field_no_headlands_publisher_ = public_node_handle_.advertise<geometry_msgs::PolygonStamped>("/field/no_headlands", 1, true);
25  field_gps_publisher_ = public_node_handle_.advertise<sensor_msgs::NavSatFix>("/gps/fix", 1, true);
26  field_swaths_publisher_ = public_node_handle_.advertise<visualization_msgs::Marker>("/field/swaths", 1, true);
27 
28 
29  std::string field_file;
30  private_node_handle_.getParam(
31  "field_file", field_file);
32 
33  f2c::Parser::importGml(field_file, fields_);
34 
35  f2c::Transform::transform(fields_[0], "EPSG:28992");
36  robot_.cruise_speed = 2.0;
37  robot_.setMinRadius(2.0);
38  double headland_width = 3.0*robot_.op_width;
39  }
40 
41  void VisualizerNode::publish_topics(void) {
42  auto gps = transf_.getRefPointInGPS(fields_[0]);
43  gps_.longitude = gps.getX();
44  gps_.latitude = gps.getY();
45  gps_.altitude = gps.getZ();
46  gps_.header.stamp = ros::Time::now();
47  gps_.header.frame_id = "base_link";
48  field_gps_publisher_.publish(gps_);
49 
50  auto f = fields_[0].field.clone();
51  f2c::hg::ConstHL hl_gen_;
52  F2CCell no_headlands = hl_gen_.generateHeadlands(f, optim_.headland_width).getGeometry(0);
53 
54  geometry_msgs::PolygonStamped polygon_st;
55  polygon_st.header.stamp = ros::Time::now();
56  polygon_st.header.frame_id = "base_link";
57  conversor::ROS::to(f.getCellBorder(0), polygon_st.polygon);
58  field_polygon_publisher_.publish(polygon_st);
59  polygon_st.polygon.points.clear();
60 
61  geometry_msgs::PolygonStamped polygon_st2;
62  polygon_st2.header.stamp = ros::Time::now();
63  polygon_st2.header.frame_id = "base_link";
64  conversor::ROS::to(no_headlands.getGeometry(0), polygon_st2.polygon);
65  field_no_headlands_publisher_.publish(polygon_st2);
66  polygon_st2.polygon.points.clear();
67 
68 
69 
70  F2CSwaths swaths;
71  f2c::sg::BruteForce swath_gen_;
72  if (automatic_angle_) {
73  switch (sg_objective_) {
74  case 0 : {
75  f2c::obj::SwathLength obj;
76  swaths = swath_gen_.generateBestSwaths(obj, robot_.op_width, no_headlands);
77  break;
78  }
79  case 1 : {
80  f2c::obj::NSwath obj;
81  swaths = swath_gen_.generateBestSwaths(obj, robot_.op_width, no_headlands);
82  break;
83  }
84  case 2 : {
85  f2c::obj::FieldCoverage obj;
86  swaths = swath_gen_.generateBestSwaths(obj, robot_.op_width, no_headlands);
87  break;
88  }
89  }
90  }
91  else {
92  swaths = swath_gen_.generateSwaths(optim_.best_angle,
93  robot_.op_width, no_headlands);
94  }
95 
96  F2CSwaths route;
97  switch (opt_route_type_) {
98  case 0 : {
99  f2c::rp::BoustrophedonOrder swath_sorter;
100  route = swath_sorter.genSortedSwaths(swaths);
101  break;
102  }
103  case 1 : {
104  f2c::rp::SnakeOrder swath_sorter;
105  route = swath_sorter.genSortedSwaths(swaths);
106  break;
107  }
108  case 2 : {
109  f2c::rp::SpiralOrder swath_sorter(6);
110  route = swath_sorter.genSortedSwaths(swaths);
111  break;
112  }
113  case 3 : {
114  f2c::rp::SpiralOrder swath_sorter(4);
115  route = swath_sorter.genSortedSwaths(swaths);
116  break;
117  }
118  }
119 
120  F2CPath path;
121  f2c::pp::PathPlanning path_planner;
122 
123  switch(opt_turn_type_) {
124  case 0 : {
125  f2c::pp::DubinsCurves turn;
126  path = path_planner.searchBestPath(robot_, route, turn);
127  break;
128  }
129  case 1 : {
130  f2c::pp::DubinsCurvesCC turn;
131  path = path_planner.searchBestPath(robot_, route, turn);
132  break;
133  }
134  case 2 : {
135  f2c::pp::ReedsSheppCurves turn;
136  path = path_planner.searchBestPath(robot_, route, turn);
137  break;
138  }
139  case 3 : {
140  f2c::pp::ReedsSheppCurvesHC turn;
141  path = path_planner.searchBestPath(robot_, route, turn);
142  break;
143  }
144  }
145 
146 
147  visualization_msgs::Marker marker_swaths;
148  marker_swaths.header.frame_id = "base_link";
149  marker_swaths.header.stamp = ros::Time::now();
150  marker_swaths.action = visualization_msgs::Marker::ADD;
151  marker_swaths.pose.orientation.w = 1.0;
152  marker_swaths.type = visualization_msgs::Marker::LINE_STRIP;
153  marker_swaths.scale.x = 1.0;
154  marker_swaths.scale.y = 1.0;
155  marker_swaths.scale.z = 1.0;
156  marker_swaths.color.b = 1.0;
157  marker_swaths.color.a = 1.0;
158  geometry_msgs::Point ros_p;
159 
160  for (auto&& s : path.states) {
161  conversor::ROS::to(s.point, ros_p);
162  marker_swaths.points.push_back(ros_p);
163  }
164  field_swaths_publisher_.publish(marker_swaths);
165  }
166 
167  void VisualizerNode::rqt_callback(fields2cover_ros::F2CConfig &config, uint32_t level) {
168  robot_.op_width = config.op_width;
169  robot_.setMinRadius(config.turn_radius);
170  optim_.best_angle = config.swath_angle;
171  optim_.headland_width = config.headland_width;
172  automatic_angle_ = config.automatic_angle;
173  sg_objective_ = config.sg_objective;
174  opt_turn_type_ = config.turn_type;
175  opt_route_type_ = config.route_type;
176  publish_topics();
177  }
178 }
179 
180 
fields2cover_ros
Definition: Fields2CoverVisualizerNode.h:19
s
XmlRpcServer s
conversor.h
f
f
conversor::ROS::to
static void to(const F2CPoint &_point, GeometryMsgs::Point32 &_p32)
Definition: conversor.cpp:12
Fields2CoverVisualizerNode.h
std
ros::Time::now
static Time now()


fields2cover_ros
Author(s):
autogenerated on Tue Feb 7 2023 03:46:06