13 #include <dynamic_reconfigure/server.h>
14 #include <fields2cover_ros/F2CConfig.h>
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);
29 std::string field_file;
30 private_node_handle_.getParam(
31 "field_file", field_file);
33 f2c::Parser::importGml(field_file, fields_);
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;
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();
47 gps_.header.frame_id =
"base_link";
48 field_gps_publisher_.publish(gps_);
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);
54 geometry_msgs::PolygonStamped polygon_st;
56 polygon_st.header.frame_id =
"base_link";
58 field_polygon_publisher_.publish(polygon_st);
59 polygon_st.polygon.points.clear();
61 geometry_msgs::PolygonStamped polygon_st2;
63 polygon_st2.header.frame_id =
"base_link";
65 field_no_headlands_publisher_.publish(polygon_st2);
66 polygon_st2.polygon.points.clear();
71 f2c::sg::BruteForce swath_gen_;
72 if (automatic_angle_) {
73 switch (sg_objective_) {
75 f2c::obj::SwathLength obj;
76 swaths = swath_gen_.generateBestSwaths(obj, robot_.op_width, no_headlands);
81 swaths = swath_gen_.generateBestSwaths(obj, robot_.op_width, no_headlands);
85 f2c::obj::FieldCoverage obj;
86 swaths = swath_gen_.generateBestSwaths(obj, robot_.op_width, no_headlands);
92 swaths = swath_gen_.generateSwaths(optim_.best_angle,
93 robot_.op_width, no_headlands);
97 switch (opt_route_type_) {
99 f2c::rp::BoustrophedonOrder swath_sorter;
100 route = swath_sorter.genSortedSwaths(swaths);
104 f2c::rp::SnakeOrder swath_sorter;
105 route = swath_sorter.genSortedSwaths(swaths);
109 f2c::rp::SpiralOrder swath_sorter(6);
110 route = swath_sorter.genSortedSwaths(swaths);
114 f2c::rp::SpiralOrder swath_sorter(4);
115 route = swath_sorter.genSortedSwaths(swaths);
121 f2c::pp::PathPlanning path_planner;
123 switch(opt_turn_type_) {
125 f2c::pp::DubinsCurves turn;
126 path = path_planner.searchBestPath(robot_, route, turn);
130 f2c::pp::DubinsCurvesCC turn;
131 path = path_planner.searchBestPath(robot_, route, turn);
135 f2c::pp::ReedsSheppCurves turn;
136 path = path_planner.searchBestPath(robot_, route, turn);
140 f2c::pp::ReedsSheppCurvesHC turn;
141 path = path_planner.searchBestPath(robot_, route, turn);
147 visualization_msgs::Marker marker_swaths;
148 marker_swaths.header.frame_id =
"base_link";
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;
160 for (
auto&&
s : path.states) {
162 marker_swaths.points.push_back(ros_p);
164 field_swaths_publisher_.publish(marker_swaths);
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;