Ros入门学习003——小乌龟跟随

小乌龟跟随实验

思路:
1、在gui中生成两只小乌龟,并利用tf发布两只乌龟相对base_link的坐标
2、将乌龟1的全局坐标转换到乌龟2的局部坐标下,通过/turtle2/cmd_vel话题发布移动指令,试turtle2朝着turtle1的方向跟随

<turtle_spawn.py>
生成第二只乌龟

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time:2021/9/29 下午3:08
# @Author:ljt
import rospy
from turtlesim.srv import Spawn,SpawnRequest
def turtle_spawn(x,y,theta,name):
    Client=rospy.ServiceProxy('/spawn',Spawn)
    Client.wait_for_service()
    req=SpawnRequest()
    req.x=x
    req.y=y
    req.theta=theta
    req.name=name
    try:
        response=Client.call(req)
        rospy.loginfo("New turtle's name:%s",response.name)
    except Exception as e:
        rospy.logerr('Spawn Error:%s',e)
if __name__ == '__main__':
    rospy.init_node('turtle_spawn')
    turtle_spawn(1.0,1.0,0,'turtle2')

<tf_turtle_publisher.py>
通过话题/turtle/pose获取乌龟在全局的坐标,并用tf发布

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time:2021/9/29 下午3:24
# @Author:ljt
import rospy
import sys
import tf2_ros
import tf
from turtlesim.msg import Pose
from geometry_msgs.msg import TransformStamped
def CallbackFunction(pose,turtle_name):
    broadcaster = tf2_ros.StaticTransformBroadcaster()
    tfs = TransformStamped()
    tfs.header.frame_id = 'base_link'
    tfs.header.seq = rospy.Time.now()
    tfs.header.seq = 102
    tfs.child_frame_id = turtle_name
    tfs.transform.translation.x = pose.x
    tfs.transform.translation.y = pose.y
    tfs.transform.translation.z = 0
    qtn = tf.transformations.quaternion_from_euler(0, 0, pose.theta)
    tfs.transform.rotation.x = qtn[0]
    tfs.transform.rotation.y = qtn[1]
    tfs.transform.rotation.z = qtn[2]
    tfs.transform.rotation.w = qtn[3]
    broadcaster.sendTransform(tfs)
if __name__ == '__main__':
    rospy.init_node('tf_turtle_pubilsher')
    '''由launch文件传入参数,当传入一个参数时,sys.argv有四位参数,其中第二位为
    传入参数,其他为系统信息'''
    turtle_name=sys.argv[1]
    rospy.logwarn('%s',turtle_name)
    sub=rospy.Subscriber('/'+turtle_name+'/pose',Pose,CallbackFunction,(turtle_name),queue_size=100)
    rospy.spin()

<tf_turtle_following.py>
将turtle1的全局坐标转换到turtle2的局部坐标,在控制turtle2调整角度和速度进行跟随

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time:2021/9/29 下午6:13
# @Author:ljt
import rospy
import tf2_ros
from geometry_msgs.msg import Twist
import numpy as np
def turtle_following():
    rospy.init_node('turtle_following')
    pub=rospy.Publisher('/turtle2/cmd_vel',Twist,queue_size=100)
    buffer=tf2_ros.Buffer()
    sub=tf2_ros.TransformListener(buffer)
    rate=rospy.Rate(10)
    follow_msg=Twist()
    while(not rospy.is_shutdown()):
        rate.sleep()
        try:
            trans_pose=buffer.lookup_transform('turtle2','turtle1',rospy.Time(0))
            trans_x=trans_pose.transform.translation.x
            trans_y=trans_pose.transform.translation.y
            trans_z=trans_pose.transform.translation.z
            follow_msg.linear.x=0.5*np.sqrt(np.power(trans_x,2)+np.power(trans_y,2))
            if (trans_x==0):
                trans_x=0.001
            if (trans_x<0 and trans_y<0):
                follow_msg.angular.z = -4 * np.arctan(trans_y / trans_x)
            else:
                follow_msg.angular.z=4*np.arctan(trans_y/trans_x)
            pub.publish(follow_msg)
        except Exception as e:
            rospy.logerr('Following Error:%s',e)
if __name__ == '__main__':
    turtle_following()

<turtle_following.launch>
launch文件启动各节点

<launch>
	<node pkg="turtlesim" type="turtlesim_node" name="turtle_gui" output="screen"/>
	<node pkg="turtlesim" type="turtle_teleop_key" name="turtle_keyboard" output="screen"/>
	<node pkg="turtle_follow" type="turtle_spawn.py" name="turtle_spawn" output="screen"/>
	<!--分别获取并tf发布两只乌龟的全局坐标-->
	<node pkg="turtle_follow" type="tf_turtle_publisher.py" name="tf_turtle1_publisher" output="screen" args="turtle1"/>
	<node pkg="turtle_follow" type="tf_turtle_publisher.py" name="tf_turtle2_publisher" output="screen" args="turtle2"/>
	<node pkg="turtle_follow" type="tf_turtle_following.py" name="tf_turtle_following" output="screen"/>
</launch>
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值