|
From: <tf...@us...> - 2009-09-03 20:52:38
|
Revision: 23783
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=23783&view=rev
Author: tfoote
Date: 2009-09-03 20:52:28 +0000 (Thu, 03 Sep 2009)
Log Message:
-----------
removing stuff now on the wiki
Modified Paths:
--------------
pkg/trunk/stacks/geometry/tf/mainpage.dox
Modified: pkg/trunk/stacks/geometry/tf/mainpage.dox
===================================================================
--- pkg/trunk/stacks/geometry/tf/mainpage.dox 2009-09-03 20:50:25 UTC (rev 23782)
+++ pkg/trunk/stacks/geometry/tf/mainpage.dox 2009-09-03 20:52:28 UTC (rev 23783)
@@ -5,113 +5,6 @@
@b tf is a library for keeping track of coordinate frames. There are both C++ and Python bindings.
- - @ref overview
- - @ref utilities
- - @ref python
- - @ref cpp
- - @ref faq
-
-
-@page utilities tf Utilities
-@section debugging_utilities Debugging Utilities
-@subsection tf_monitor tf_monitor
-This node will listen to the tf_message topic and generate statistics to help diagnose problems.
-
-\todo WRITE ME
-
-@subsection tf_echo tf_echo
-This node will echo the latest transform between two frames.
-
-\todo WRITE ME
-
-@subsection view_frames view_frames
-This node will generate a pdf of the current transform tree.
-
-\todo WRITE ME
-
-@section helper_utilities Helper Utilites
-@subsection transform_sender transform_sender
-This is a command line tool to send static transforms periodically.
-
-\todo WRITE ME
-
-@page overview Overview of Functionality
-@section summary Summary
-tf is a software library that keeps track of coordinate frames.
-The main interface to the tf is through the tf::Transformer class. This class
-provides all the necessary external interfaces and can be used independently of ROS.
-For ROS integrations, there are two subclasses of tf::Transformer that assist with
-receiving and publishing transforms.
-The tf::TransformListener class automatically listens for transform messages sent over ROS and updates the Transformer.
-The tf::TransformBroadcaster class publishes transforms to ROS.
-
-tf utilizes the Linear Math libraries from the Bullet Physics engine.
-
-@section library Library
-The tf::Transformer class is a ROS-indepdent library. Its design, implementation and rationale
-are described below.
-
-@subsection storage Storage
-Transforms are expressed as a combination of a translation and rotation in 3D space,
-in the form of a tf::Vector3 and a tf::Quaternion.
-Each transform has an associated frame id, parent id, and time stamp. Each transform added
-to the library is pushed into a list sorted by time for each frame id.
-
-@subsection lookup Transform Composition
-To generate a transform between two arbitrary frames,
-the structure of the relationship between the frames is assumed to be a tree.
-To find the spanning set between any two frames, tf starts by recursively finding
-the parent of both the target frame and the source frame. These will both end at the root of the tree.
-tf then steps back down the tree and removes all but the closest common parent.
-
-@subsection timetransform Transforms in Time
-It is often useful to know where an object is in relation to something at a different time. Data is timestamped
-when observed, however it is often used at a non negligable time later than when it was observed. To handle this the
-tf API provide an advanced form of each method which can transform a Stamped piece of data from it's observed frame and
-time into a different frame at a different time. This is only possible if there exists a frame in which the object is
-expected not to move relative to during the period between the starting time and the ending time. This frame is explicitly
-passed in the function calls for it will vary based on the context. For example when building a local map using the odometric
-frame as a fixed frame is usually the most accurate, while when working with navigational landmarks and loop closures a map
-based frame will be more accurate. Or if an object is currently being held in the gripper the gripper frame is the best frame to
-declare as the fixed frame.
-
-A very common example is an object observed as a vehicle is driving. Two seconds later as the
-vehicle approaches the obstacle, the navigation algorithms would like to know where the object is in relation to the vehicle.
-To provide this a tf user would call the advanced version of the API with the odometric frame as the fixed frame. The source frame
-and time would have been set by the data source, and the target frame would be set to the vehicle frame and the time requested could
-either be "now" or "latest". Tf's response will be to transform the data at the time it was observed into the fixed frame. It will
-then jump the timestamp to the target_time. After jumping the timestamp to the target time the transform from the fixed frame to the
-target frame is computed. Thus tf can effectively transform data in time.
-
-An accurate choice of the fixed frame is a required for validity of this method. The above choice of the odometric frame would
-be incorrect if the vehicle had a robotic hand which grabbed the
-object when it was observed. Two seconds after grabbing the object, it would be in the same position
-with relation to the hand, and and not the vehicle,
-so the fixed frame would be hand. And the lookup would show the position of the object in the body frame the same
-distance from the hand as observed when picked up, but the position of the hand may have changed relative to the body in
-the two seconds, to which this would be robust.
-
-@subsection exceptions Exceptions
-Exceptions are thrown for bad lookup requests and malformed trees. The exceptions all derive from tf::TransformException,
-which is a subclass of std::RuntimeError and have the method what() defined for debugging.
-The specific exception classes are tf::LookupException, tf::MaxDepthException and tf::ConnectivityException.
-
-Timing is also important to tf, so there a tf::ExtrapolationException that is thrown in cases when
-the time requested is too far from data currently stored in the library. There are two common cases when this would
-happen. If requests are made of tf faster than new transforms are added, it will complain.
-The other case is if the requested time is too far in the past to be in the list of transforms stored. The tf::Transformer constructor allows you to configure the amount of extrapolation
-and how long to keep data.
-
-@subsection computation Computation
-tf does not do any background processing. All transforms are generated when requested and
-transform lists are updated during the inserting function call. Transform updates
-simply prune expired transforms from the end of the list.
-
-All interfaces use the std::string representation of the frame id, although
-these strings are mapped to numerical ids interally to avoid calculations with strings.
-
-
-@page cpp C++ Usage
@section usage Common Usage
For most ROS use cases, the basic tf::Transformer library is not used directly.
@@ -150,307 +43,12 @@
-Stamped version of all of the above inherits from the data type and also has:
- ros::Time stamp_
- std::string frame_id_
- - std::string parent_frame_id_ (only used for Stamped<Transform> )
+ - std::string child_frame_id_ (only used for Stamped<Transform> )
- There are analogous ROS messages in std_msgs to the Stamped data types.
- Time represented by ros::Time and ros::Duration in ros/time.h in roscpp
-@page python Python Usage
-@page faq FAQ
-
-@section debugging Common Debugging Questions
-@subsection introspection Introspection Methods
- - How can I see what transforms are in the system?
-
-Use the script view_frames in the tf package. By default, it listens
-to tf messages for 5 seconds and produces a pdf (frames.pdf) that graphs
-all frames heard from.
-The "--node=NODE_NAME" option can assist with debugging transform issues with a
-specific node.
-The --node option will query the TransformListener instance in NODE_NAME
-for its transform information.
-This will allow you to see what that TransformListener is processing.
-
- - How can I see how fast transforms are coming in.
-
-Use \ref tf_monitor
-
- - How can I see what a specific transform's value is?
-
-Use \ref tf_echo
-
-@subsection tf_self_transform TF_SELF_TRANSFORM
- - What does a warning about TF_SELF_TRANFORM mean?
-
-TF_SELF_TRANSFORM errors occur when a transform is published with
-itself listed as its parent. TF will ignore this information for it
-is impossible to be your own parent.
-This means that there is a problem with the source of that transform
-which is listed as the authority in the error message.
-
-@subsection old_data TF_OLD_DATA
- - What does a warning about TF_OLD_DATA mean?
-
-TF_OLD_DATA errors mean that a transform is attempted to be added to the system,
-but the data is greater than cache_time_ before the most recent data
-recieved for this link.
-
- - What is the most common reason to see TF_OLD_DATA errors?
-
-The most common cause of TF_OLD_DATA warnings are if rostime has gone backwards.
-This can be caused by restarting a bag playback or restarting a simulator.
-The fix for this is to send an Empty message the topic /reset_time, there is a button in rviz
-to do this.
-
- - Is there any other way to see TF_OLD_DATA warnings?
-
-Yes, if there there is any outdated or delayed source of transforms this may appear.
-The error message will tell you what is the authority which is sending the
-outdated data. If it is running in a ros node you can use view_frames to
-determine the more recent authority. See \ref view_frames.
-
-@subsection tf_no_frame_id TF_NO_FRAME_ID
- - What does the error TF_NO_FRAME_ID mean?
-
-The TF_NO_FRAME_ID error means that a transform was attempted to be set
-with an empty frame_id. This transform will be ignored by TF.
-
-@subsection tf_no_parent_id TF_NO_PARENT_ID
- - What does the error TF_NO_PARENT_ID mean?
-
-The TF_NO_PARENT_ID error means that a transform was attempted to be set
-with an empty parent_id. This transform will be ignored by TF.
-
-@subsection tf_nan_input TF_NAN_INPUT
- - What does the error TF_NAN_INPUT mean?
-
-The TF_NAN_INPUT error means that a transform was attempted to be set
-with a nan value. This transform will be ignored by TF.
-
-@subsection extrapolation_exceptions Extrapolation Exceptions
- - I'm seeing an ExtrapolationException which is always X seconds in
-the past. Why?
-
-A constant offset extrapolation error is often caused by a lack of
-synchronization of the clocks between computers. One computer thinks
-it is ahead of the other and consequently the data received on a
-different machine will be off consistently. As new data comes in ,the
-closest data will always be the same distance away resulting in the
-constant ExtrapolationException.
-
- - I'm seeing a very small extrapolation in the future. Where might that come from?
-
-In a distributed system information is not available instantaneously
-in all parts of the system. Depending on the setup is is possible for
-data to be available before all the transforms necessary are available.
-The recommended way to deal with this is to use a tf::MessageFilter.
-
- - I'm seeing a huge (~1.2E9 second) extrapolation error, why is that?
-
-Most likely this is a problem that part of the ROS system is running
-on sim time, while part is running without simtime. Make sure that all
-nodes are started while time is being published. And set the param
-"/using_sim_time" to true so that on startup there will not be a race
-condition for what mode ros::Time is running in.
-
-@subsection lookup_exception LookupException
- - What does a LookupException mean?
-
-A LookupException is thrown in the case that a frame id requested
-does not exist in the tf tree.
-
- - What does "Recursed too deep into graph" mean?
-
-This error is thrown when tf finds itself taking more than MAX_GRAPH_DEPTH
-steps to try to find the top of the tree. This is set high enough that the
-only common reason to hit this point is if the graph has a cycle in it.
-Look at the rest of the error message and see if any cycles exist.
-The program \ref tf_monitor will show who is publishing which transform.
-
-@subsection connectivity_exceptions ConnectivityException
- - What does a connectivityException tell me about my robot?
-
-A ConnectivityException says that it is not possible to transform
-between the requested frame_ids.
-
- - What are common sources of ConnectivityExceptions?
-
-The most common source of a ConnectivityException is that a tf
-authority is not publishing an intermediate transform required
-to get between the source and target frame. If you are running
-a large launch script look carefully for any nodes crashing
-or failing to start. The best utility to see what is being
-published is view_frames see \ref view_frames for usage.
-
- - What do the different versions of ConnectivityExceptions mean?
-
- - NO_PARENT at top of tree means that one or both of the target and source
-frame ids has NO_PARENT set as it's parent_id.
- - No Common Parent Case A is when the forward transform list is zero length
-and the top of the inverse transform list is not the target frame_id.
- - No Common Parent Case B is when the forward and inverse transform lists
-are both zero length, but the target and source frame_ids are not the same.
- - No Common Parent Case C is when the end of the forward transform list
-is not equal to the source_frame, but the inverse list is zero length.
- - No Common Parent Case D is the same as B.
-
- - What does "Could not find a common time" mean?
-
-This will be thrown when using getLatestCommonTime
-(usually done by passing a time of 0 to the tf API)
-if the frames exist and are connected
-but there are no overlapping data in time. Often this is caused by
-one or more frames stopping being published.
-
-
-@subsection datatypes_questions Data Types
- - What is the difference between a tf::Transform and a tf::Pose, or
-for that matter a tf::Point and a tf::Vector3? They look like the
-same data type.
-
-Think of it as the difference between time and duration. Pose is a
-specific location, like time. You can take the difference between two
-Poses, and you get a transform, which is like a duration. However,
-you can't add two Poses. You can add a duration to a time and get a
-time, likewise you can add a transform to a Pose and get a Pose. A
-Point is like Pose, while a Vector3 is like a Transform showing the
-difference between two Points.
-
-There's also another difference in interpretation in the difference
-between point and vector. A vector subject to transformation will
-only apply the rotational elements for a vector is always at the
-origin. Or another way to say it is that a vector subject to
-translation is unchanged. The same holds for a transform, but you
-usually think of applying a transform to another transform, you chain
-them. The same goes for vectors.
-
-@section faq_usage Usage Questions
- - How can tf be used in a 3D-mapping framework? The
-very simple example that I had in mind for the past few days was the
-following: given 4 sensing devices: 1 Hokuyo, 1 SwissRanger SR4000, 1
-Videre STOC and 1 Thermal FLIR camera. The first 3 produce point
-clouds, and the last 3, images. After calibration, you get the
-necessary rotation matrices that you need to use to transform the
-SwissRanger point cloud into the left camera on the STOC, respectively
-the thermal image into left STOC, etc. While collecting data, you
-constantly need to apply these rotation matrices to the point clouds
-generated by some sensors, to annotate your 3D points with texture
-(RGB), thermal information, etc
-
-This is exactly where you want to use tf::TransformListener. The point
-cloud aggregator will be recieving messages over ROS from all of the
-sensors, in their respective date types. However, say the
-Hokuyo is mounted on the base, the Videre stereo camera is on the head, and the
-swiss ranger is on the left arm. The aggregating process has no idea
-where all these coordinate frames actually are in space. However the
-mechanims control process knows where the head and arms are in
-relationship to the base. And the localization process knows where
-the base is in relationship to the world. Now if they are all
-publishing transforms using their own broadcaster instances. All the
-aggregator node needs to do is instantiate the TransformListener and
-it will be able to relate the data from the videre to the data from
-the hokuyo and data from the swiss ranger. The TransformListener
-class will extract all that information from the ROS network and
-provide it automatically to the Transformer base class. The
-Transformer class then can provide the aggregator with any transform
-they wish. The goal is that the end user doesn't have to worry about
-collecting any transforms, and they are automatically cached in time
-and can provide interpolated or extrapolated results if desired. The
-way to make this easy for the the developer/user is the use of frame
-ids. The frame id's are simply strings which uniquely identify
-coordinate frames. When the system is operating, if you have a point
-cloud arrive from the videre it will be in the "videre_camera_frame"
-to use it in whatever frame you want simply transform it to the frame
-id of the frame you want and use it.
-
- - Can I transform a Point Cloud?
-
-Yes it's in tf package right now it will be moving to a point cloud package soon.
-
- - Can I transform a laser scan into a point cloud in a different frame?
-Yes see the laser_scan package.
-
- - Would it be possible to bring back into tf a method a-la
-setWithMatrix () ? Are there any disadvantages (other than re-exposing
-NEWMAT) on doing that ?
-
-I would suggest you take a look at the bullet data types. The
-btTransform can be constructed using a btQuaternion and a btVector3,
-or a btMatrix and a btVector3. And a btMatrix3x3 will take 9 values
-in it's constructor. Thus you can do
-tf_instance.setTransform(Stamped<tf::Transform>(tf::Transform(btMatrix3x3(1,2,3,4,5,6,7,8,9),
-btVector3(x,y,z)), ros::Time().fromSec(timestamp), "frame id", "parent
-id"));
-
- - I already have my own classes for converting to/from all 4 major
-representations (euler, axis-angle, rotation matrices and
-quaternions), but it would be great to use tf instead, as that makes
-all these routines nicely accessible from virtually all nodes that we
-want to build in ROS later.
-
-Take a look at the bullet headers they provide all these through the
-btQuaternion and btMatrix3x3 classes.
-
- - Is there a way to declare static transforms independent of a
-specific process? Some transforms seem better suited to be defined as
-parameters independent of a specific node.
-
-There is no way to define a static transform in tf. This is a
-design decision to make sure that log files retain relevancy. Since
-nodes can start and stop at any time, they must be able to get all
-necessary data starting at any time. The ROS Parameter Server could hold
-this data. However, preserving the state of the Parameter Server
-between sessions, especially when logging, is complicated. Thus, the
-solution we have chosen is to simply republish static transforms
-periodically. This make sure that at startup a node knows about all
-transforms, and it also means that logging the topic /tf_message
-captures all state of transforms making log files complete.
-
- - Some code (such as amcl_player.cc) refers to an expiration time for
-transforms. How does the concept of transforms that expire interact
-with the transform library's attempts at interpolation/extrapolation?
-Is this documented anywhere?
-
-The concept of expiring transforms is not actually supported. What
-amcl_player and a few others do is date their transforms in the
-future. This is to get around the problem that a chain of transforms
-is only as current as the oldest link of the chain. The future dating
-of a transform allows the slow transform to be looked up in the
-intervening period between broadcasts. This technique is dangerous in
-general, for it will cause tf to lag actual information, for tf will
-assume that information is correct until it's timestamp in the future
-passes. However for transforms which change only very slowly this lag
-will not be observable, which is why it is valid for amcl_player to
-use this. It can safely be used for static transforms. I highly
-recommend being careful with future dating any measurements. Another
-technique available is to allow extrapolation. And either technique
-can creep up on you and cause unusual behavior which is untraceable.
-
- - Can different expiration limits be set for specific transforms?
- After all, I would expect different transforms to update at rates
- that are potentially orders of magnitude different.
-
-For the current implementation, it is simply how far you future date
-your data for that transform. Remember, this will cause the transform
-to lag by however much you future date the values. I do not recommend
-this for any value which is expected to change at a rate more than a
-slight drift correction (ala amcl_player).
-
- - It doesn't make sense to extrapolate some transforms (such as the
- current estimated localization offset). How do these transforms
- interact with transforms that should be interpolated/extrapolated
- when combining multiple transforms?
-
-Our experimentation has shown that interpolation is fine, but
-extrapolation almost always ends up becoming more of a problem than a
-solution. If you are having trouble with data being ready before
-transforms are available I suggest using the tf::MessageFilter class in
-tf. It will queue incoming data until transforms are available.
-Having tried allowing "just a little" extrapolation, waiting for
-accurate data to be available has proved a much better approach.
-
-
*/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|