Skip to content

Transform 対応#

基本的な挙動#

uml diagram

Broadcaster側#

  • broadcaster側は、sendTransformを実行したスレッドがそのままpublishしている
  • TransformBroadcasterのコンストラクタに与えたノードで 新規にpublisherが作られる(該当コード)
  • sendTransformに入力するメッセージの型はgeometry_msgs::msg::TransformStamped。
  • 内部では、tf2_msgs::msg::TFMessageへ変換して/tfトピックへpublishしている。
#geometry_msgs/TransformStamped.msg
std_msgs/Header header
string child_frame_id
geometry_msgs/Transform transform
#tf2_msgs::msg::TFMessage
geometry_msgs/TransformStamped[] transforms

listener側#

最新の座標データを保持した座標データのバッファを介して以下が行われる

  • /tfトピックから受け取ったメッセージの保存 (常にバッファを最新にさせるため、別スレッドで処理を行わせるのが基本。)
  • チュートリアル通りにtf2ros::TransformListener(buf) と使った場合: /tfのsubscribe、バッファの更新は非同期に行われる。(非同期に行いたかったという旨が論文にかかれている) 新規スレッド&新規エグゼキュータ&新規ノードが作成させる Listener毎に transform_listener_impl** 名前を持ったノードが作成される(だから量産されてる) 対応するコンストラクタ

新規スレッドを立ち上げさせず、アプリケーション側で制御する方法もある。(動作未確認)

ノードも引数に与え、こっちのコンストラクタでListenerを構築すること。 スレッドやエグゼキュータの生成も行われず、引数に与えたノードで/tfのsubscribe&バッファの更新が行われる

https://github.com/ros2/geometry2/blob/210791c2a57a5c7c87e348e684c9cdc28469cb70/tf2_ros/include/tf2_ros/transform_listener.h#L89

lookupTransformなどを受け付け、指定された時刻の座標変換を取得 (こちらはアプリケーション側が呼ぶAPI)

デフォルトだと、10秒前まで座標を遡れるようになっている。 https://github.com/ros2/geometry2/blob/16562cee8694c11f1f82b2bdbde2814fca1c7954/tf2/include/tf2/buffer_core.h#L70

tfの動作シーケンス図#

トレースポイントの挿入箇所 https://github.com/ros2/geometry2

※ シーケンス図は説明のために簡略化しています。

uml diagram


TransformBroadcasterがrclcpp::publishするまで

uml diagram


メッセージ受信からBufferに格納するまで

uml diagram


lookupTransformを実行してBufferから取得するまで

uml diagram


waitForTransformを実行

uml diagram


TransformStampedFuture使用ケース

中身はC++のFuture。そのまま使うことができる。 その他、rclcpp.spin_until_future_complete()なども使用できる。

using TransformStampedFuture =
    std::shared_future<geometry_msgs::msg::TransformStamped>;

using TransformReadyCallback =
    std::function<void (const TransformStampedFuture &)>;

uml diagram


waitForTransformの引数であるTransformReadyCallbackを使用するケース

uml diagram