TF2小乌龟实操

我们进行时间,生产两个小乌龟,操纵一个,并使另一个能跟踪前一个小乌龟运动。

我们先写下产生孪生乌龟的文档:

#include "ros/ros.h"
#include "turtlesim/Spawn.h"

int main(int argc, char*argv[]){
    setlocale(LC_ALL,"");
    ros::init(argc,argv,"practice01_pub");
    ros::NodeHandle n;
    ros::ServiceClient client=n.serviceClient<turtlesim::Spawn>("/spawn");
    turtlesim::Spawn spawn;
    spawn.request.x=5.0;
    spawn.request.y=5.0;
    spawn.request.theta=1.57;
    spawn.request.name="turtle2";

    client.waitForExistence();
   bool flag=client.call(spawn);
    if(flag){
        ROS_INFO("New turtle created successfully, name: %s",spawn.request.name.c_str());
    }
    else{
        ROS_INFO("Failed to create");
    }

    return 0;
}

再写发布方文件:

#include "ros/ros.h"
#include "turtlesim/Pose.h"
#include "tf2_ros/transform_broadcaster.h"
#include "geometry_msgs/TransformStamped.h"
#include "tf2/LinearMath/Quaternion.h"

std::string  turtlename;

void doPose(const turtlesim::Pose::ConstPtr& pose){
    static tf2_ros::TransformBroadcaster pub;
    geometry_msgs::TransformStamped ts;
    ts.header.frame_id="world";
    ts.header.stamp=ros::Time::now();
    ts.child_frame_id= turtlename;
    ts.transform.translation.x=pose->x;
    ts.transform.translation.y=pose->y;
    ts.transform.translation.z=0.0;

    tf2::Quaternion qtn;
    qtn.setRPY(0,0,pose->theta);
    ts.transform.rotation.x=qtn.getX();
    ts.transform.rotation.y=qtn.getY();
    ts.transform.rotation.z=qtn.getZ();
    ts.transform.rotation.w=qtn.getW();

    pub.sendTransform(ts);
}

int main(int  argc,char *argv[]){
    setlocale(LC_ALL,"");
    ros::init(argc,argv,"practice01_dynamic");
    ros::NodeHandle n;

    if(argc!= 2){
        ROS_ERROR("Please input the right paraments!");
        return 1;
    }
    else{
            turtlename=argv[1];
    }

    ros::Subscriber sub=n.subscribe( turtlename + "/pose" , 100 , doPose );

    ros::spin();
    return 0;
}

再写订阅方文档:

#include "ros/ros.h"
#include "tf2_ros/transform_listener.h"
#include "tf2_ros/buffer.h"
#include "geometry_msgs/PointStamped.h"
#include "tf2_geometry_msgs/tf2_geometry_msgs.h"

int main(int argc,char* argv[]){
    setlocale(LC_ALL,"");
    ros::init(argc,argv,"practice01_sub");
    ros::NodeHandle n;

    tf2_ros::Buffer buffer;
    tf2_ros::TransformListener listener(buffer);
    geometry_msgs::PointStamped ps;
    ps.header.frame_id="turtle1";
    ps.header.stamp=ros::Time(0.0);
    ps.point.x=2.0;
    ps.point.y=3.0;
    ps.point.z=5.0;

    //ros::Duration(1).sleep();
    ros::Rate rate(10);

    while(ros::ok()){
        geometry_msgs::PointStamped ps_out;
        
        try{
            ps_out=buffer.transform(ps,"world");
            ROS_INFO("transformed location:( %.2f , %.2f , %.2f ), the reference frame: %s",
            ps_out.point.x,
            ps_out.point.y,
            ps_out.point.z,
            ps_out.header.frame_id.c_str()
            );
        }
        catch(const std::exception& e)
        {
           ROS_INFO("exception message: %s",e.what());
        }

        rate.sleep();
        ros::spinOnce();
    }

    return 0;
}

最后写控制乌龟的文档:

#include "ros/ros.h"
#include "tf2_ros/transform_listener.h"
#include "tf2_ros/buffer.h"
#include "geometry_msgs/PointStamped.h"
#include "tf2_geometry_msgs/tf2_geometry_msgs.h"
#include "geometry_msgs/Twist.h"

int  main(int argc,char* argv[]){
    setlocale(LC_ALL,"");
    ros::init(argc,argv,"practice01_control");
    ros::NodeHandle n;

    tf2_ros::Buffer buffer;
    tf2_ros::TransformListener sub(buffer);

    ros::Publisher pub=n.advertise<geometry_msgs::Twist>("/turtle2/cmd_vel",100);

    ros::Rate rate(10);
    while (ros::ok())
    {
        try
        {
            geometry_msgs::TransformStamped son1Toson2 = buffer.lookupTransform("turtle2", "turtle1", ros::Time(0)); //son2:目标坐标系 son1:原坐标系 ros::Time(0):取间隔最短的两个坐标关系帧计算相对关系
            // ROS_INFO("former reference frame: %s, current reference frame: %s, transformation: %.2f, %.2f, %.2f",
            //          son1Toson2.child_frame_id.c_str(),//turtle2
            //          son1Toson2.header.frame_id.c_str(),//turtle1
            //          son1Toson2.transform.translation.x,
            //          son1Toson2.transform.translation.y,
            //          son1Toson2.transform.translation.z);
            
            geometry_msgs::Twist twist;            // x=k1*sqr(x^2+y^2) and z=k2*arctan(y/x)
            twist.linear.x = 0.75 * sqrt(pow(son1Toson2.transform.translation.x,2)+pow(son1Toson2.transform.translation.y,2));//only need to set x of linear velocity and z of angular velocity
            twist.angular.z=4*atan2(son1Toson2.transform.translation.y,son1Toson2.transform.translation.x);
            pub.publish(twist);
        }
        catch(const std::exception& e)
        {
            ROS_INFO("Error warning: %s",e.what());
        }

        rate.sleep();
        ros::spinOnce();
    }

    return 0;
}

然后我们写以下的launch文件:

<launch>
    <group>
        <node pkg="turtlesim" type="turtlesim_node" name="turtle1" output="screen" />
        <node pkg="turtlesim" type="turtle_teleop_key" name="key1" output="screen" />
        <node pkg="practice01_tf2" type="practice01_dynamic" name="pub1" args="/turtle1" output="screen" />
        <node pkg="practice01_tf2" type="practice01_sub" name="sub1" args="/turtle1" output="screen" />
        <node pkg="practice01_tf2" type="practice01_control" name="control" output="screen" />
    </group>

    <group>
        <node pkg="practice01_tf2" type="practice01_pub" name="turtle2" output="screen" />
        <node pkg="practice01_tf2" type="practice01_dynamic" name="pub2" args="/turtle2" output="screen" />
        <node pkg="practice01_tf2" type="practice01_sub" name="sub2" args="/turtle2" output="screen" />
    </group>
</launch>

然后我们直接发布launch文件即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值