24 #include <gazebo/common/Time.hh> 25 #include <gazebo/common/CommonTypes.hh> 26 #include <gazebo/math/Vector3.hh> 36 sdf::ElementPtr _sdf) {
38 gzdbg << __FUNCTION__ <<
"() called." << std::endl;
43 std::string service_name =
"world/get_octomap";
44 std::string octomap_pub_topic =
"world/octomap";
45 getSdfParam<std::string>(_sdf,
"octomapPubTopic", octomap_pub_topic,
47 getSdfParam<std::string>(_sdf,
"octomapServiceName", service_name,
50 gzlog <<
"Advertising service: " << service_name << std::endl;
58 rotors_comm::Octomap::Request& req, rotors_comm::Octomap::Response& res) {
59 gzlog <<
"Creating octomap with origin at (" << req.bounding_box_origin.x
60 <<
", " << req.bounding_box_origin.y <<
", " 61 << req.bounding_box_origin.z <<
"), and bounding box lengths (" 62 << req.bounding_box_lengths.x <<
", " << req.bounding_box_lengths.y
63 <<
", " << req.bounding_box_lengths.z
64 <<
"), and leaf size: " << req.leaf_size <<
".\n";
66 if (req.filename !=
"") {
68 std::string
path = req.filename;
70 gzlog << std::endl <<
"Octree saved as " << path << std::endl;
72 ROS_ERROR(
"The octree is NULL. Will not save that.");
75 common::Time now =
world_->GetSimTime();
76 res.map.header.frame_id =
"world";
77 res.map.header.stamp =
ros::Time(now.sec, now.nsec);
83 if (req.publish_octomap) {
84 gzlog <<
"Publishing Octomap." << std::endl;
88 common::SphericalCoordinatesPtr sphericalCoordinates =
world_->GetSphericalCoordinates();
89 ignition::ignition::math::Vector3d origin_cartesian(0.0, 0.0, 0.0);
90 ignition::ignition::math::Vector3d origin_spherical = sphericalCoordinates->
91 SphericalFromLocal(origin_cartesian);
93 res.origin_latitude = origin_spherical.X();
94 res.origin_longitude = origin_spherical.Y();
95 res.origin_altitude = origin_spherical.Z();
100 const ignition::math::Vector3d & seed_point,
const ignition::math::Vector3d & bounding_box_origin,
101 const ignition::math::Vector3d & bounding_box_lengths,
const double leaf_size) {
107 std::stack<octoignition::math::Vector3d > to_check;
108 to_check.push(octoignition::math::Vector3d (seed_point.x, seed_point.y, seed_point.z));
110 while (to_check.size() > 0) {
111 octoignition::math::Vector3d p = to_check.top();
113 if ((p.x() > bounding_box_origin.x - bounding_box_lengths.x / 2) &&
114 (p.x() < bounding_box_origin.x + bounding_box_lengths.x / 2) &&
115 (p.y() > bounding_box_origin.y - bounding_box_lengths.y / 2) &&
116 (p.y() < bounding_box_origin.y + bounding_box_lengths.y / 2) &&
117 (p.z() > bounding_box_origin.z - bounding_box_lengths.z / 2) &&
118 (p.z() < bounding_box_origin.z + bounding_box_lengths.z / 2) &&
122 to_check.push(octoignition::math::Vector3d (p.x() + leaf_size, p.y(), p.z()));
123 to_check.push(octoignition::math::Vector3d (p.x() - leaf_size, p.y(), p.z()));
124 to_check.push(octoignition::math::Vector3d (p.x(), p.y() + leaf_size, p.z()));
125 to_check.push(octoignition::math::Vector3d (p.x(), p.y() - leaf_size, p.z()));
126 to_check.push(octoignition::math::Vector3d (p.x(), p.y(), p.z() + leaf_size));
127 to_check.push(octoignition::math::Vector3d (p.x(), p.y(), p.z() - leaf_size));
136 gazebo::physics::RayShapePtr ray,
137 const double leaf_size) {
138 ignition::math::Vector3d start_point = central_point;
139 ignition::math::Vector3d end_point = central_point;
142 std::string entity_name;
144 start_point.x += leaf_size / 2;
145 end_point.x -= leaf_size / 2;
146 ray->SetPoints(start_point, end_point);
147 ray->GetIntersection(dist, entity_name);
149 if (dist <= leaf_size)
return true;
151 start_point = central_point;
152 end_point = central_point;
153 start_point.y += leaf_size / 2;
154 end_point.y -= leaf_size / 2;
155 ray->SetPoints(start_point, end_point);
156 ray->GetIntersection(dist, entity_name);
158 if (dist <= leaf_size)
return true;
160 start_point = central_point;
161 end_point = central_point;
162 start_point.z += leaf_size / 2;
163 end_point.z -= leaf_size / 2;
164 ray->SetPoints(start_point, end_point);
165 ray->GetIntersection(dist, entity_name);
167 if (dist <= leaf_size)
return true;
173 const rotors_comm::Octomap::Request& msg) {
174 const double epsilon = 0.00001;
175 const int far_away = 100000;
176 ignition::math::Vector3d bounding_box_origin(msg.bounding_box_origin.x,
177 msg.bounding_box_origin.y,
178 msg.bounding_box_origin.z);
181 ignition::math::Vector3d bounding_box_lengths(msg.bounding_box_lengths.x + epsilon,
182 msg.bounding_box_lengths.y + epsilon,
183 msg.bounding_box_lengths.z + epsilon);
184 double leaf_size = msg.leaf_size;
193 gazebo::physics::PhysicsEnginePtr engine =
world_->PhysicsEngine();
194 engine->InitForThread();
195 gazebo::physics::RayShapePtr ray =
196 boost::dynamic_pointer_cast<gazebo::physics::RayShape>(
197 engine->CreateShape(
"ray", gazebo::physics::CollisionPtr()));
199 std::cout <<
"Rasterizing world and checking collisions" << std::endl;
202 leaf_size / 2 + bounding_box_origin.x - bounding_box_lengths.x / 2;
203 x < bounding_box_origin.x + bounding_box_lengths.x / 2;
x += leaf_size) {
205 round(100 * (
x + bounding_box_lengths.x / 2 - bounding_box_origin.x) /
206 bounding_box_lengths.x);
207 std::cout <<
"\rPlacing model edges into octomap... " << progress
211 leaf_size / 2 + bounding_box_origin.y - bounding_box_lengths.y / 2;
212 y < bounding_box_origin.y + bounding_box_lengths.y / 2;
214 for (
double z = leaf_size / 2 + bounding_box_origin.z -
215 bounding_box_lengths.z / 2;
216 z < bounding_box_origin.z + bounding_box_lengths.z / 2;
218 ignition::math::Vector3d point(
x,
y, z);
229 std::cout <<
"\rFlood filling freespace... ";
230 FloodFill(ignition::math::Vector3d (bounding_box_origin.x + leaf_size / 2,
231 bounding_box_origin.y + leaf_size / 2,
232 bounding_box_origin.z + bounding_box_lengths.z / 2 -
234 bounding_box_origin, bounding_box_lengths, leaf_size);
235 FloodFill(ignition::math::Vector3d (bounding_box_origin.x + leaf_size / 2,
236 bounding_box_origin.y + leaf_size / 2,
237 bounding_box_origin.z - bounding_box_lengths.z / 2 +
239 bounding_box_origin, bounding_box_lengths, leaf_size);
246 leaf_size / 2 + bounding_box_origin.x - bounding_box_lengths.x / 2;
247 x < bounding_box_origin.x + bounding_box_lengths.x / 2;
x += leaf_size) {
249 round(100 * (
x + bounding_box_lengths.x / 2 - bounding_box_origin.x) /
250 bounding_box_lengths.x);
251 std::cout <<
"\rFilling closed spaces... " << progress <<
"% ";
254 leaf_size / 2 + bounding_box_origin.y - bounding_box_lengths.y / 2;
255 y < bounding_box_origin.y + bounding_box_lengths.y / 2;
257 for (
double z = leaf_size / 2 + bounding_box_origin.z -
258 bounding_box_lengths.z / 2;
259 z < bounding_box_origin.z + bounding_box_lengths.z / 2;
270 std::cout <<
"\rOctomap generation completed " << std::endl;
bool ServiceCallback(rotors_comm::Octomap::Request &req, rotors_comm::Octomap::Response &res)
void updateInnerOccupancy()
ros::Publisher octomap_publisher_
void setClampingThresMax(double thresProb)
double getOccupancy() const
void FloodFill(const ignition::math::Vector3d &seed_point, const ignition::math::Vector3d &bounding_box_origin, const ignition::math::Vector3d &bounding_box_lengths, const double leaf_size)
GZ_REGISTER_WORLD_PLUGIN(GazeboRosInterfacePlugin)
void setProbHit(double prob)
void Load(physics::WorldPtr _parent, sdf::ElementPtr _sdf)
Load the plugin.
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
octomap::OcTree * octomap_
virtual OcTreeNode * setNodeValue(const OcTreeKey &key, float log_odds_value, bool lazy_eval=false)
static bool binaryMapToMsg(const OctomapT &octomap, Octomap &msg)
void setProbMiss(double prob)
void publish(const boost::shared_ptr< M > &message) const
OcTreeNode * search(double x, double y, double z, unsigned int depth=0) const
void CreateOctomap(const rotors_comm::Octomap::Request &msg)
Creates octomap by floodfilling freespace.
bool writeBinary(const std::string &filename)
ros::NodeHandle node_handle_
static const bool kPrintOnPluginLoad
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
void setOccupancyThres(double prob)
virtual ~OctomapFromGazeboWorld()
bool CheckIfInterest(const ignition::math::Vector3d ¢ral_point, gazebo::physics::RayShapePtr ray, const double leaf_size)
void setClampingThresMin(double thresProb)
Octomap plugin for Gazebo.