tf 变换 重要文章总结

让我知道 这样可以 直接转换点的坐标 通过监听transform
ROS之tf空间坐标变换浅析 - https://blog.csdn.net/u014587147/article/details/76377024

class TransformListener : public Transformer { 
public:
  TransformListener(ros::Duration max_cache_time = ros::Duration(DEFAULT_CACHE_TIME), bool spin_thread = true);
  TransformListener(const ros::NodeHandle& nh,
                    ros::Duration max_cache_time = ros::Duration(DEFAULT_CACHE_TIME), bool spin_thread = true);

  ~TransformListener();
...
  void transformPoint(const std::string& target_frame, const geometry_msgs::PointStamped& stamped_in, geometry_msgs::PointStamped& stamped_out) const;
 ...
}

geometry_msgs 的所有消息种类, 了解每个消息的内容及相互之间的差异

ROS Message Types 很全, 每个有详细的链接, http://wiki.ros.org/geometry_msgs

ROS Message Types
Accel
AccelStamped
AccelWithCovariance
AccelWithCovarianceStamped
Inertia
InertiaStamped
Point
Point32
PointStamped
Polygon
PolygonStamped
Pose
Pose2D
PoseArray
PoseStamped
PoseWithCovariance
PoseWithCovarianceStamped
Quaternion
QuaternionStamped
Transform
TransformStamped
Twist
TwistStamped
TwistWithCovariance
TwistWithCovarianceStamped
Vector3
Vector3Stamped
Wrench
WrenchStamped

http://wiki.ros.org/geometry_msgs

主要的 tf 相关数据类型
ROS与C++入门教程-tf-数据类型 https://www.ncnynl.com/archives/201702/1305.html

tf::StampedTransform

tf::StampedTransform 是tf::Transforms的特例,它要求frame_id 、stamp 、child_frame_id.
** \brief The Stamped Transform datatype used by tf */
class StampedTransform : public tf::Transform
{
public:
  ros::Time stamp_; ///< The timestamp associated with this transform                                                                                                                                                                                                                                                        
  std::string frame_id_; ///< The frame_id of the coordinate frame  in which this transform is defined                                                                                                                                                                                                                       
  std::string child_frame_id_; ///< The frame_id of the coordinate frame this transform defines                                                                                                                                                                                                                              
  StampedTransform(const tf::Transform& input, const ros::Time& timestamp, const std::string & frame_id, const std::string & child_frame_id):
    tf::Transform (input), stamp_ ( timestamp ), frame_id_ (frame_id), child_frame_id_(child_frame_id){ };

  /** \brief Default constructor only to be used for preallocation */
  StampedTransform() { };

  /** \brief Set the inherited Traonsform data */
  void setData(const tf::Transform& input){*static_cast<tf::Transform*>(this) = input;};

};

有些比较好的查看函数
ROS Indigo 进阶笔记 (二) tf http://makaidong.com/youngpan1101/1/156515_10690007.html

$ rosrun tf view_frames  (生成 pdf 文档)
$ evince frames.pdf   (打开 pdf 文档)
$ rosrun rviz rviz -d `rospack find turtle_tf`/rviz/turtle_rviz.rviz //使用 rviz 更直观地查看三个坐标系随时间的变换
$ rosrun tf tf_echo /world /turtle1
530 void DatabaseUpdator::LaserCallback(const sensor_msgs::LaserScan::ConstPtr& scan)
531 {
532     ros::Rate rate(GET_LASER_FRE);
533     tf::StampedTransform transform;
534     tf::TransformListener listener_;
535     ROS_INFO("Receive Laser Data, Length is  [%lu]", scan->ranges.size());
536 
537     // Get info about the scan
538     float angle_min = scan->angle_min;
539     float angle_max = scan->angle_max;
540     float angle_increment = scan->angle_increment;
541     float range_min = scan->range_min;
542     float range_max = scan->range_max;
543 
544     float angle = angle_min;
545     int laser_length = sizeof(scan->ranges) / sizeof(double);
546 
547     nlohmann::json scan_points_xy_info;
548     scan_points_xy_info["scan_points"] = nlohmann::json::array();
549     nlohmann::json xycoordinate;
550 
551 
552     // get the \scan to \map transform when recieve a transform from \base_link to \map
553     try
554      {
555        listener_.waitForTransform("/map", "/base_laser_link",
556                             ros::Time::now(),  ros::Duration(3));
557 
558        listener_.lookupTransform("/map", "/base_laser_link",
559                             ros::Time(0), transform );
560       
561       }catch(tf::TransformException &e){
562        ROS_WARN("%s,%s,%d:%s\n", __FILE__, __FUNCTION__, __LINE__, e.what());
563       }
564 
565 
566 
567     // Deal with scan
568     for(std::vector<float>::const_iterator it = scan->ranges.begin();
569       it != scan->ranges.end();
570       it += 2)
571     {
572           //the angle of each laser
573           angle += 2.0 *  angle_increment;
574 
575           //Change the coordinate of the laser data
576           if(*it < range_max && *it > range_min)  // the laser data must be  in validate range
577           {
578                 // x y in local 
579                 double x_ = (*it)*cos(angle);
580                 double y_ = (*it)*sin(angle);
581 
582                 geometry_msgs::PointStamped laser_point;
583                 laser_point.header.frame_id = scan->header.frame_id;
584                 laser_point.header.stamp = ros::Time();
585                 laser_point.point.x = x_;
586                 laser_point.point.y = y_;
587                 laser_point.point.z = 0.0;
588 
589 
590                 // transform point in /scan frame to point in /map frame
591                 geometry_msgs::PointStamped base_point;
592                 base_point.header.frame_id = "map";
593                 listener_.transformPoint("/map", laser_point, base_point);
594 
595                 // Save the transformed point to queue
596                 xycoordinate["x"] = base_point.point.x;
597                 xycoordinate["y"] = base_point.point.y;
598                 scan_points_xy_info["scan_points"].push_back(xycoordinate);
599                 }
600       }
601 
602      std::string scan_points_str;
603      try{
604            scan_points_str = scan_points_xy_info.dump();
605 
606      }catch(nlohmann::json::exception& e){
607            ROS_WARN("%s,%s,%d:%s\n", __FILE__, __FUNCTION__, __LINE__, e.what());
608            return;
609      }
610     mongodb_manager_.update_db("robot_status_getscan_req", scan_points_str);
611 }
612 

猜你喜欢

转载自blog.csdn.net/Fourier_Legend/article/details/82874059
今日推荐