00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef JSK_PCL_ROS_PARTICLE_CUBOID_H_
00038 #define JSK_PCL_ROS_PARTICLE_CUBOID_H_
00039
00040 #include <pcl/point_cloud.h>
00041 #include "jsk_pcl_ros/geo_util.h"
00042
00043 namespace pcl
00044 {
00045 namespace tracking
00046 {
00047 struct _ParticleCuboid
00048 {
00049 PCL_ADD_POINT4D;
00050 union
00051 {
00052 struct
00053 {
00054 float roll;
00055 float pitch;
00056 float yaw;
00057 float dx;
00058 float dy;
00059 float dz;
00060 float weight;
00061
00062 };
00063 float data_c[8];
00064 };
00065
00066
00067 int plane_index;
00068 };
00069
00070 struct EIGEN_ALIGN16 ParticleCuboid : public _ParticleCuboid
00071 {
00072
00073
00074 inline ParticleCuboid(const ParticleCuboid& obj)
00075 {
00076 x = obj.x;
00077 y = obj.y;
00078 z = obj.z;
00079 roll = obj.roll;
00080 pitch = obj.pitch;
00081 yaw = obj.yaw;
00082 dx = obj.dx;
00083 dy = obj.dy;
00084 dz = obj.dz;
00085 weight = obj.weight;
00086 plane_index = obj.plane_index;
00087 }
00088
00089 inline ParticleCuboid()
00090 {
00091 x = y = z = roll = pitch = yaw = dx = dy = dz = weight = 0.0;
00092 data[3] = 1.0f;
00093 plane_index = -1;
00094 }
00095 inline ParticleCuboid (float _x, float _y, float _z, float _roll, float _pitch, float _yaw)
00096 {
00097 x = _x; y = _y; z = _z;
00098 roll = _roll; pitch = _pitch; yaw = _yaw;
00099 dx = dy = dz = 0.0;
00100 data[3] = 1.0f;
00101 }
00102
00103 inline Eigen::Affine3f toEigenMatrix() const
00104 {
00105 return getTransformation(x, y, z, roll, pitch, yaw);
00106 }
00107
00108 inline void fromEigen(const Eigen::Affine3f& pose)
00109 {
00110 Eigen::Vector3f pos(pose.translation());
00111 getEulerAngles(pose, roll, pitch, yaw);
00112 getVector3fMap() = pos;
00113 }
00114
00115 inline void zero()
00116 {
00117 x = y = z = roll = pitch = yaw = dx = dy = dz = weight = 0.0;
00118 }
00119
00120 inline float volume() const
00121 {
00122 return dx * dy * dz;
00123 }
00124
00125 inline float area() const
00126 {
00127 return (dx * dy + dy * dz + dz * dx) * 2.0;
00128 }
00129
00130 static pcl::tracking::ParticleCuboid
00131 toState (const Eigen::Affine3f &trans)
00132 {
00133 float trans_x, trans_y, trans_z, trans_roll, trans_pitch, trans_yaw;
00134 getTranslationAndEulerAngles (trans,
00135 trans_x, trans_y, trans_z,
00136 trans_roll, trans_pitch, trans_yaw);
00137 return pcl::tracking::ParticleCuboid (trans_x, trans_y, trans_z, trans_roll, trans_pitch, trans_yaw);
00138 }
00139
00140
00141 inline float operator [] (unsigned int i) const
00142 {
00143 switch (i)
00144 {
00145 case 0: return x;
00146 case 1: return y;
00147 case 2: return z;
00148 case 3: return roll;
00149 case 4: return pitch;
00150 case 5: return yaw;
00151 case 6: return dx;
00152 case 7: return dy;
00153 case 8: return dz;
00154 case 9: return weight;
00155 default: return 0.0;
00156 }
00157 }
00158
00159 inline void sample(
00160 const std::vector<double>& mean, const std::vector<double>& cov)
00161 {
00162
00163 }
00164
00165 inline static int stateDimension()
00166 {
00167 return 9;
00168 }
00169
00170 inline jsk_recognition_msgs::BoundingBox toBoundingBox()
00171 {
00172 jsk_recognition_msgs::BoundingBox box;
00173 Eigen::Affine3f affine = toEigenMatrix();
00174 tf::poseEigenToMsg(affine, box.pose);
00175 box.dimensions.x = dx;
00176 box.dimensions.y = dy;
00177 box.dimensions.z = dz;
00178 return box;
00179 }
00180
00181 inline std::vector<int> visibleFaceIndices(const Eigen::Vector3f local_view_point) const
00182 {
00183 std::vector<int> visible_faces;
00184 visible_faces.reserve(3);
00185 if (local_view_point[0] > 0) {
00186 visible_faces.push_back(0);
00187 }
00188 else if (local_view_point[0] < 0) {
00189 visible_faces.push_back(2);
00190 }
00191 if (local_view_point[1] > 0) {
00192 visible_faces.push_back(1);
00193 }
00194 else if (local_view_point[1] < 0) {
00195 visible_faces.push_back(3);
00196 }
00197 if (local_view_point[2] > 0) {
00198 visible_faces.push_back(4);
00199 }
00200 else if (local_view_point[2] < 0) {
00201 visible_faces.push_back(5);
00202 }
00203 return visible_faces;
00204 }
00205
00206 inline double distanceNearestToPlaneWithOcclusion(
00207 const Eigen::Vector3f& v,
00208 const std::vector<int>& visible_faces,
00209 std::vector<jsk_pcl_ros::Polygon::Ptr>& faces) const
00210 {
00211 double min_distance = DBL_MAX;
00212 for (size_t i = 0; i < visible_faces.size(); i++) {
00213 jsk_pcl_ros::Polygon::Ptr face = faces[visible_faces[i]];
00214 double d;
00215 face->nearestPoint(v, d);
00216 if (min_distance > d) {
00217 min_distance = d;
00218 }
00219 }
00220 return min_distance;
00221 }
00222
00223
00224
00225
00226 inline double signedDistanceToPlane(
00227 const Eigen::Vector3f& v, const int plane_index) const
00228 {
00229 Eigen::Vector3f n;
00230 double d;
00231 switch (plane_index)
00232 {
00233 case 0: {
00234 n = Eigen::Vector3f::UnitX();
00235 d = - 0.5 * dx;
00236 break;
00237 }
00238 case 1: {
00239 n = Eigen::Vector3f::UnitY();
00240 d = - 0.5 * dy;
00241 break;
00242 }
00243 case 2: {
00244 n = - (Eigen::Vector3f::UnitX());
00245 d = - 0.5 * dx;
00246 break;
00247 }
00248 case 3: {
00249 n = - (Eigen::Vector3f::UnitY());
00250 d = - 0.5 * dy;
00251 break;
00252 }
00253 case 4: {
00254 n = Eigen::Vector3f::UnitZ();
00255 d = - 0.5 * dz;
00256 break;
00257 }
00258 case 5: {
00259 n = - (Eigen::Vector3f::UnitZ());
00260 d = - 0.5 * dz;
00261 break;
00262 }
00263
00264 }
00265 return (n.dot(v) + d) / sqrt(n.dot(n) + d * d);
00266 }
00267
00268 inline double distanceToPlane(
00269 const Eigen::Vector3f& v, const int plane_index) const
00270 {
00271 return std::abs(signedDistanceToPlane(v, plane_index));
00272 }
00273
00274
00275
00276 inline int nearestPlaneIndex(const Eigen::Vector3f& local_v) const
00277 {
00278 const float x = local_v[0];
00279 const float y = local_v[1];
00280 const float z = local_v[2];
00281 const float abs_x = std::abs(x);
00282 const float abs_y = std::abs(y);
00283 const float abs_z = std::abs(z);
00284 if (x > 0 && abs_x >= abs_y && abs_x >= abs_z) {
00285 return 0;
00286 }
00287 else if (x < 0 && abs_x >= abs_y && abs_x >= abs_z) {
00288 return 2;
00289 }
00290 else if (y > 0 && abs_y >= abs_x && abs_y >= abs_z) {
00291 return 1;
00292 }
00293 else if (y < 0 && abs_y >= abs_x && abs_y >= abs_z) {
00294 return 3;
00295 }
00296 else if (z > 0 && abs_z >= abs_x && abs_z >= abs_y) {
00297 return 4;
00298 }
00299 else if (z < 0 && abs_z >= abs_x && abs_z >= abs_y) {
00300 return 5;
00301 }
00302 }
00303
00304 inline jsk_pcl_ros::Cube::Ptr toCube() const
00305 {
00306 Eigen::Affine3f pose = toEigenMatrix();
00307 Eigen::Vector3f dimensions(dx, dy, dz);
00308 jsk_pcl_ros::Cube::Ptr cube(new jsk_pcl_ros::Cube(Eigen::Vector3f(pose.translation()),
00309 Eigen::Quaternionf(pose.rotation()),
00310 dimensions));
00311 return cube;
00312 }
00313
00314
00315 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00316 };
00317
00318 inline ParticleCuboid operator* (const ParticleCuboid& p, const Eigen::Affine3f& transform)
00319 {
00320 Eigen::Affine3f particle_affine = p.toEigenMatrix();
00321 Eigen::Affine3f transformed_affine = transform * particle_affine;
00322 ParticleCuboid new_p;
00323 new_p.x = transformed_affine.translation()[0];
00324 new_p.y = transformed_affine.translation()[1];
00325 new_p.z = transformed_affine.translation()[2];
00326 getEulerAngles(transformed_affine, new_p.roll, new_p.pitch, new_p.yaw);
00327 new_p.dx = p.dx;
00328 new_p.dy = p.dy;
00329 new_p.dz = p.dz;
00330 return new_p;
00331 }
00332
00333
00334 inline pcl::tracking::ParticleCuboid operator+ (const ParticleCuboid& a, const ParticleCuboid& b)
00335 {
00336 pcl::tracking::ParticleCuboid newp;
00337 newp.x = a.x + b.x;
00338 newp.y = a.y + b.y;
00339 newp.z = a.z + b.z;
00340 newp.roll = a.roll + b.roll;
00341 newp.pitch = a.pitch + b.pitch;
00342 newp.yaw = a.yaw + b.yaw;
00343 newp.dx = a.dx + b.dx;
00344 newp.dy = a.dy + b.dy;
00345 newp.dz = a.dz + b.dz;
00346 return (newp);
00347 }
00348
00349 inline pcl::tracking::ParticleCuboid operator * (const ParticleCuboid& p, double val)
00350 {
00351 pcl::tracking::ParticleCuboid newp;
00352 newp.x = static_cast<float> (p.x * val);
00353 newp.y = static_cast<float> (p.y * val);
00354 newp.z = static_cast<float> (p.z * val);
00355 newp.roll = static_cast<float> (p.roll * val);
00356 newp.pitch = static_cast<float> (p.pitch * val);
00357 newp.yaw = static_cast<float> (p.yaw * val);
00358 newp.dx = static_cast<float> (p.dx * val);
00359 newp.dy = static_cast<float> (p.dy * val);
00360 newp.dz = static_cast<float> (p.dz * val);
00361 return (newp);
00362 }
00363
00364 inline pcl::tracking::ParticleCuboid operator * (double val, const ParticleCuboid& p)
00365 {
00366 return p * val;
00367 }
00368
00369 inline pcl::tracking::ParticleCuboid operator- (const ParticleCuboid& a, const ParticleCuboid& b)
00370 {
00371 return a + (-1.0) * b;
00372 }
00373
00374 }
00375
00376
00377 template<>
00378 class DefaultPointRepresentation<pcl::tracking::ParticleCuboid>: public PointRepresentation<pcl::tracking::ParticleCuboid>
00379 {
00380 public:
00381 DefaultPointRepresentation()
00382 {
00383 nr_dimensions_ = 10;
00384 }
00385
00386 virtual void
00387 copyToFloatArray (const pcl::tracking::ParticleCuboid &p, float * out) const
00388 {
00389 for (int i = 0; i < nr_dimensions_; ++i)
00390 out[i] = p[i];
00391 }
00392 };
00393
00394 }
00395
00396
00397
00398
00399
00400 POINT_CLOUD_REGISTER_POINT_STRUCT (pcl::tracking::_ParticleCuboid,
00401 (float, x, x)
00402 (float, y, y)
00403 (float, z, z)
00404 (float, roll, roll)
00405 (float, pitch, pitch)
00406 (float, yaw, yaw)
00407 (float, dx, dx)
00408 (float, dy, dy)
00409 (float, dz, dz)
00410 (float, weight, weight)
00411 )
00412 POINT_CLOUD_REGISTER_POINT_WRAPPER(pcl::tracking::ParticleCuboid, pcl::tracking::_ParticleCuboid)
00413
00414
00415 #endif