ROS 生成新的小乌龟
生成小乌龟和复位
生成小乌龟-前置条件 turtlesim
我们知道,要生成小乌龟需要调用服务,那么这个service是什么呢?
首先,我们要在终端调用turtlesim
rosrun turtlesim turtlesim_node
然后查看它所调用的service
rosservice list
可以看到目前调用到的service
/clear
/key/get_loggers
/key/set_logger_level
/kill
/reset
/rosout/get_loggers
/rosout/set_logger_level
/spawn
/turtle1/get_loggers
/turtle1/set_logger_level
/turtle1/set_pen
/turtle1/teleport_absolute
/turtle1/teleport_relative
其中/spawn就是它生成新乌龟的服务
那我们接下来就要看看他的类型是啥样的,都用到了什么参数
rosservice info /spawn
可以看到下面的日志输出,其中Type和Args是很重要的内容,Type对应了我们写c++文件和python文件时要导入的自定义的消息类型,Args是调用服务时所需要输入的参数。
Node: /turtle1
URI: rosrpc://liqunzhao-virtual-machine:34355
Type: turtlesim/Spawn
Args: x y theta name
liqunzhao@liqunzhao-virtu
生成小乌龟-文件配置 CMakeList和package.xml
有了上述的内容,我们就可以开始写代码了,这里我用的是clion来写的,首先我们要生成新的pkg包
cd 工作目录/src
catkin_create_pkg turtle_control roscpp rospy std_msgs
cd ..
catkin_make
然后我们要编辑turtle_control目录下的CMakeList和package.xml
CMakeList.txt
CMakeList里修改下面几个部分
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
turtlesim
)
add_executable(turtle_service_client src/turtle_service_client.cpp)
target_link_libraries(turtle_service_client
${catkin_LIBRARIES}
)
package.xml
增加由turtlesim带来的新功能
<exec_depend>turtlesim</exec_depend>
<build_depend>turtlesim</build_depend>
生成小乌龟-代码编写C++
由于服务端系统已经给了,我们只需要写client端,把我们的需求提交到/spawn,并响应就可以了。
#include "ros/ros.h"
#include "turtlesim/Spawn.h"
int main(int argc, char *argv[]) {
setlocale(LC_ALL, "");
ros::init(argc, argv, "turtle_service_client");
ros::NodeHandle nh;
// create client, note that the name of client should be /spawn
ros::ServiceClient client = nh.serviceClient<turtlesim::Spawn>("/spawn");
// we need to give the vlaue of the service type msg : turtlesim::Spawn
turtlesim::Spawn spawn;
// request data
spawn.request.x =1.0;
spawn.request.y =4;
spawn.request.theta =1.57;
spawn.request.name ="hey_turtle";
// send data
ros::service::waitForService("/spawn");
// note that client.call is a bool type
bool flag = client.call(spawn);
if (flag){
ROS_INFO("turtle already done, name:%s",spawn.response.name.c_str());
}
else {
ROS_INFO("Error");
}
return 0;
}
生成小乌龟-代码编写Python
#! /usr/bin/env python
# coding utf-8
import rospy
from turtlesim.srv import Spawn, SpawnRequest, SpawnResponse
if __name__ == '__main__':
rospy.init_node("spawn_by_py")
client = rospy.ServiceProxy("/spawn", Spawn)
request = SpawnRequest()
request.x = 1.0
request.y = 4.0
request.theta = 1.57
request.name = "hey_turtle_py4"
response = SpawnResponse(request)
client.wait_for_service()
try:
doCall = client.call(request)
rospy.loginfo("the new turtle is down,\n%s", response.name)
except Exception as e:
rospy.loginfo("error")
#! /usr/bin/env python
# coding utf-8
import rospy
from turtlesim.srv import Spawn, SpawnRequest, SpawnResponse
if __name__ == '__main__':
rospy.init_node("spawn_by_py")
client = rospy.ServiceProxy("/spawn", Spawn)
request = SpawnRequest()
request.x = 1.0
request.y = 4.0
request.theta = 1.57
request.name = "hey_turtle_py4"
client.wait_for_service()
try:
doCall = client.call(request)
rospy.loginfo("the new turtle is down,named:%s", doCall.name)
except Exception as e:
rospy.loginfo("error")
小乌龟复位
依葫芦画瓢,那么我们也可以进行小乌龟的复位。可以看到之前的service list里有/reset的这个服务口。那么我们就需要对它进行编写。我们就在当前建立好的基础下继续编写。
rosservice info /reset
Node: /turtle1
URI: rosrpc://liqunzhao-virtual-machine:34355
Type: std_srvs/Empty
Args:
可以看到这个Type和Args。由于Args不需要提交任何参数,所以这里我们可以不使用request了
CMakeList.txt
CMakeList里修改下面这个部分
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
turtlesim
std_srvs
)
add_executable(turtle_reset src/turtle_reset.cpp)
target_link_libraries(turtle_reset
${catkin_LIBRARIES}
)
package.xml
不需要修改了
小乌龟复位代码
#include "ros/ros.h"
#include "std_srvs/Empty.h"
int main(int argc, char *argv[]) {
setlocale(LC_ALL, "");
ros::init(argc, argv, "turtle_reset");
ros::NodeHandle nh;
ros::ServiceClient client = nh.serviceClient<std_srvs::Empty>("/reset");
std_srvs::Empty reset;
// request data
// send data
ros::service::waitForService("/reset");
bool flag = client.call(reset);
if (flag){
ROS_INFO("turtle_reset");
}
else {
ROS_INFO("Error");
}
return 0;
}