创建工作空间
mkdir -p work/src
catkin_make
source devel/setup.bash
echo "export ROS_PACKAGE_PATH=~/username/work:${ROS_PACKAGE_PATH}" >> ~/.bashrc"
//添加工作空间到ROS环境变量中,否则命令不知道去哪儿找包 ,不知道去哪儿找结点。
echo $ROS_PACKAGE_PATH //rospack find 会从中搜索
cd ~/work
catkin_make
- 创建一个话题发布者和一个订阅者
cd ~/work/src
catkin_create_pkg myros std_msgs roscpp
- 创建发布者
#include "ros/ros.h" // /opt/ros/hydo/include/ros/ros.h
#include "std_msgs/String.h" // /opt/ros/hydro/include/std_msgs/String.h
#include <sstream> // /usr/include/c++/4.6/sstream
int main(int argc, char** argv)
{
ros::init(argc,argv,"example1_a"); // nnode name
ros::NodeHandle n;
ros::Publisher chatter_pub = n.advertise<std_msgs::String>("message",1000);
ros::Rate rate(1);
int count = 0;
while(ros::ok())
{
std_msgs::String msg;
std::stringstream ss;
ss << "I am CAFFEE_LEEMAN"<< count ;
msg.data = ss.str();
ROS_INFO("%s",msg.data.c_str());
chatter_pub.publish(msg);
count++;
ros::spinOnce(); //NO call back , but ok. spinonce can execute following code after it ,
rate.sleep();
}
return 0;
}
- 订阅者
#include "ros/ros.h"
#include "std_msgs/String.h"
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("I heard [%s]",msg->data.c_str());
}
//String (string data)
//ConstPtr& 声明形参为引用传递时用法 包名::类名::ConstPtr&
int main(int argc, char** argv)
{
ros::init(argc, argv,"example1_b");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("message",1000,chatterCallback);
ros::spin();//到此处才会回掉!!
return 0;
}
编写package.xml (1)
cmake_minimum_required(VERSION 2.8.3)
project(ch2)
find_package(catkin REQUIRED COMPONENTS roscpp std_msgs)
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES ch2
# CATKIN_DEPENDS roscpp std_msgs
# DEPENDS system_lib
)
###########
## Build ##
###########
## Specify additional locations of header files
include_directories(include ${catkin_INCLUDE_DIRS})
## Declare a C++ executable
add_executable(ex1a src/ex1_a.cpp)
add_executable(ex1b src/ex1_b.cpp)
add_dependencies(ex1a ch2_generate_messages_cpp)
add_dependencies(ex1b ch2_generate_messages_cpp)
#此处的模板写法是add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${CATKIN_EXPORTED_TARGETS})
## Specify libraries to link a library or executable target against
target_link_libraries(ex1a ${catkin_LIBRARIES} )
target_link_libraries(ex1b ${catkin_LIBRARIES} )
package.xml(2)
cmake_minimum_required(VERSION 2.8.3)
project(ch2)
find_package(catkin REQUIRED COMPONENTS roscpp std_msgs)
#均位于share目录中的包
catkin_package(
INCLUDE_DIRS include
LIBRARIES ch2
CATKIN_DEPENDS roscpp std_msgs
DEPENDS system_lib
)
###########
## Build ##
###########
## Specify additional locations of header files
##include_directories(include ${catkin_INCLUDE_DIRS})
##注解该句,是因为catkin_package(..)已经包含了include
##使用catkin_cmake,默认路径是${CATKIN_PREFIX_PATH=/OPT/ROS/HYDOR/}
## ls /opt/ros/hydro
## bin etc lib include share setup.bahs ...
## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
add_executable(ex1a src/ex1_a.cpp)
add_executable(ex1b src/ex1_b.cpp)
#add_dependencies(ex1a ch2_generate_messages_cpp)
#add_dependencies(ex1b ch2_generate_messages_cpp)
##这两句可以注解是因为cakin_package(...)的原因
## Specify libraries to link a library or executable target against
target_link_libraries(ex1a ${catkin_LIBRARIES} )
target_link_libraries(ex1b ${catkin_LIBRARIES} )
##以上两个链接库,必须,否则链接时会报错。
话题列表
robot@ubuntu:~/dev/catkin_ws$ rosnode list
/example1_a //节点名由ros::init决定,与程序名无关
/example1_b
/rosout
/rostopic_50864_1503976194535
/teleop_turtle
robot@ubuntu:~/dev/catkin_ws$ rostopic list
/message //话题名,此处为绝对作用域,带/
/rosout
/rosout_agg
/turtle1/cmd_vel
- 使用自建数据消息类型msg
在src/ch2/下mkdir msg
vim add.msg
int32 A
int32 B
int32 C
修改package.xml
<build_depend>message_generation</build_depend>
<run_depend>message_runtime</run_depend>
修改cmakelist.txt,如下:
cmake_minimum_required(VERSION 2.8.3)
project(ch2)
find_package(catkin REQUIRED COMPONENTS roscpp std_msgs message_generation)
add_message_files(FILES add.msg)
generate_messages(DEPENDENCIES std_msgs)
#generate_messages() must be called before catkin_package()顺序有要求!!!
catkin_package(
INCLUDE_DIRS include
LIBRARIES ch2
CATKIN_DEPENDS roscpp std_msgs
DEPENDS system_lib
)
###########
## Build ##
###########
## Specify additional locations of header files
#include_directories(include ${catkin_INCLUDE_DIRS})
## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
add_executable(ex1a src/ex1_a.cpp)
add_executable(ex1b src/ex1_b.cpp)
#add_dependencies(ex1a ch2_generate_messages_cpp)
#add_dependencies(ex1b ch2_generate_messages_cpp)
## Specify libraries to link a library or executable target against
target_link_libraries(ex1a ${catkin_LIBRARIES} )
target_link_libraries(ex1b ${catkin_LIBRARIES} )
编译
catkin_make
显示消息类型--检查
rosmsg show ch2/add
int32 A
int32 B
int32 C
- 创建srv文件
新建srv文件目录 catkin_ws/src/ch2/
mkdir srv
cd srv && vim addTwoInts.srv
输入如下:
int32 A
int32 B
int32 C
---
int32 SUM
- 为srv更改packge.xml(其实和修改msg时一样,现在不用改了)
<build_depend>message_generation</build_depend>
<run_depend>message_runtime</run_depend>
- 为srv更改cmakelist.txt,如下:
cmake_minimum_required(VERSION 2.8.3)
project(ch2)
find_package(catkin REQUIRED COMPONENTS
roscpp
std_msgs
message_generation #msg,srv必须
)
add_message_files(FILES add.msg)
add_service_files(FILES addsrv.srv) #srv 新加
generate_messages(DEPENDENCIES std_msgs) #srv msg 必须,相同
#generate_messages() must be called before catkin_package()
catkin_package(
INCLUDE_DIRS include
LIBRARIES ch2
CATKIN_DEPENDS roscpp std_msgs
DEPENDS system_lib
)
###########
## Build ##
###########
## Specify additional locations of header files
#include_directories(include ${catkin_INCLUDE_DIRS})
## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
add_executable(ex1a src/ex1_a.cpp)
add_executable(ex1b src/ex1_b.cpp)
#add_dependencies(ex1a ch2_generate_messages_cpp)
#add_dependencies(ex1b ch2_generate_messages_cpp)
## Specify libraries to link a library or executable target against
target_link_libraries(ex1a ${catkin_LIBRARIES} )
target_link_libraries(ex1b ${catkin_LIBRARIES} )
- 检查
rossrv show ch2/addsrv
不编译,也可以使用上面命令检查,但是catkin_make之后,会生成相应消息或者服务的头文件。
- 重点——消息和头文件的生成(编译后,路径在哪里呢?)
robot@ubuntu:~/dev/catkin_ws$ cd devel/
robot@ubuntu:~/dev/catkin_ws/devel$ ls
env.sh include setup.bash _setup_util.py share
etc lib setup.sh setup.zsh
robot@ubuntu:~/dev/catkin_ws/devel$ cd include/
robot@ubuntu:~/dev/catkin_ws/devel/include$ ls
ch2
robot@ubuntu:~/dev/catkin_ws/devel/include$ cd ch2/
robot@ubuntu:~/dev/catkin_ws/devel/include/ch2$ ls
add.h addsrv.h addsrvRequest.h addsrvResponse.h ###重点###阿达
- 使用自定义服务
touch addTwoIntsSrv.cpp
#include "ros/ros.h"
#include "add/AddTwoInts.h"
bool adds(add::AddTwoInts::Request &req,
add::AddTwoInts::Response &res)
{
res.sum = req.a + req.b;
ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
ROS_INFO("sending back response: [%ld]", (long int)res.sum);
return true;
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "add_two_ints_server");
ros::NodeHandle n;
ros::ServiceServer service = n.advertiseService("add_two_ints", adds);
ROS_INFO("Ready to add two ints.");
ros::spin();
return 0;
}
客户端
touch addTwoIntClt.cpp
#include "ros/ros.h"
#include "add/AddTwoInts.h"
#include <cstdlib>
int main(int argc, char **argv)
{
ros::init(argc, argv, "add_two_ints_client");
if (argc != 3)
{
ROS_INFO("usage: add_two_ints_client X Y");
return 1;
}
ros::NodeHandle n;
ros::ServiceClient client = n.serviceClient<add::AddTwoInts>("add_two_ints");
add::AddTwoInts srv;
srv.request.a = atoll(argv[1]);
srv.request.b = atoll(argv[2]);
if (client.call(srv))
{
ROS_INFO("Sum: %ld", (long int)srv.response.sum);
}
else
{
ROS_ERROR("Failed to call service add_two_ints");
return 1;
}
return 0;
}
此处使用服务消息的头文件和用法和自定义话题一样!!包名/服务文件名
cmakelists.txt同样需要注意先添加消息文件,再生成消息
- 使用话题发布自定义消息
在add/msg touch Num2.msg
int32 A
int32 B
int32 C
touch topictalker.cpp
#include "ros/ros.h"
#include "add/Num2.h"
int main(int argc, char **argv)
{
ros::init(argc, argv, "example3_a");
ros::NodeHandle n;
ros::Publisher pub = n.advertise<add::Num2>("addTwoIntTopic", 1000);
ros::Rate loop_rate(10);
while (ros::ok())
{
add::Num2 msg;
msg.A = 1;
msg.B = 2;
msg.C = 3;
pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
}
return 0;
}
touch topiclister.cpp
#include "ros/ros.h"
#include "add/Num2.h"
void messageCallback(const add::Num2::ConstPtr& msg)
{
ROS_INFO("I heard: [%d] [%d] [%d]", msg->A, msg->B, msg->C);
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "example3_b");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("addTwoIntTopic", 1000, messageCallback);
ros::spin();
return 0;
}
注意的是头文件的用法
add/Num2.msg 前面包名/后面自定义消息文件名
在Cmakelists.txt中切记要先add_message_files(FILES add.msg)
再generate_messages(DEPENDENCIES std_msgs)
___________________________python_________________________________
话题
talker.py
#!/usr/bin/env python
import rospy
from std_msgs.msg import String
# rospy.init_node(NAME, ...), it tells rospy the name of your node
# until rospy has this information, it cannot start communicating with the ROS Master.
# the name must be a base name, i.e. it cannot contain any slashes "/".
def talker():
pub = rospy.Publisher('chatter',String,queue_size=10)
rospy.init_node('talker',anonymous=True)
rate = rospy.Rate(10)
while not rospy.is_shutdown():
hello_str = "hello world%s" % rospy.get_time()
rospy.loginfo(hello_str)
rospy.logdebug(hello_str)
pub.publish(hello_str)
rate.sleep()
if __name__ == '__main__':
try:
talker()
except rospy.ROSInterruptException:
pass
listen.py
#!/usr/bin/env python
import rospy
from std_msgs.msg import String
def callback(data):
rospy.loginfo(rospy.get_caller_id() + "I heard %s ", data.data)
def listener():
rospy.init_node('listenner',anonymous=True)
rospy.Subscriber('chatter',String,callback)
rospy.spin()
#rospy.spin() simply keeps your node from exiting until the node has been shutdown.
#Unlike roscpp, rospy.spin() does not affect the subscriber callback functions, as those have their own threads.
if __name__ == '__main__':
listener()
服务
add_two_ints_server.py
#!/usr/bin/env python
from hellopy.srv import *
import rospy
def handle_add_two_ints(req):
print "Returning [%s + %s = %s]" % (req.a,req.b,(req.a+req.b))
return AddTwoIntsResponse(req.a+req.b)
def add_two_ints_server():
rospy.init_node('add_two_ints_server')
s = rospy.Service('add_two_ints',AddTwoInts,handle_add_two_ints)
print "Ready to add two ints"
rospy.spin()
if __name__ == '__main__':
add_two_ints_server()
add_two_ints_client.py
#!/usr/bin/env python
import rospy
from hellopy.srv import *
def add_two_ints_client(x,y):
rospy.wait_for_service('add_two_ints')
try:
add_two_ints = rospy.ServiceProxy('add_two_ints',AddTwoInts)
resp1 = add_two_ints(x,y)
return resp1.sum
except rospy.ServiceException, e:
print "Service call failed:%s" % e
def usage():
return "%s [x,y]" % sys.argv[0]
if __name__ == '__main__':
if len(sys.argv)== 3:
x = int(sys.argv[1])
y = int(sys.argv[2])
else:
print usage()
sys.exit(1)
print "Requesting %s + %s" % (x,y)
print"%s + %s = %s " % (x,y,add_two_ints_client(x,y))
python 如果自定的数据类型或者服务,也是需要编译的,如果是标准的话题或者数据格式,可以不编译
CMakeLists.txt
cmake_minimum_required(VERSION 2.8.3)
project(hellopy)
find_package(catkin REQUIRED COMPONENTS
geometry_msgs
roscpp
rospy
std_msgs
message_generation
)
## Generate messages in the 'msg' folder
add_message_files(
FILES
Num.msg)
## Generate services in the 'srv' folder
add_service_files(
FILES
AddTwoInts.srv)
generate_messages(
DEPENDENCIES
std_msgs
)
catkin_package(
INCLUDE_DIRS include
LIBRARIES hellopy
CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs message_runtime
DEPENDS system_lib
)
###########
## Build ##
###########
include_directories(
# include
${catkin_INCLUDE_DIRS}
)
# add_executable(${PROJECT_NAME}_node src/hellopy_node.cpp)
# target_link_libraries(${PROJECT_NAME}_node
# ${catkin_LIBRARIES}
# )
mkdir -p work/src
catkin_make
source devel/setup.bash
echo "export ROS_PACKAGE_PATH=~/username/work:${ROS_PACKAGE_PATH}" >> ~/.bashrc"
- 创建一个话题发布者和一个订阅者
cd ~/work/src
- 创建发布者
#include "ros/ros.h" // /opt/ros/hydo/include/ros/ros.h
#include "std_msgs/String.h" // /opt/ros/hydro/include/std_msgs/String.h
#include <sstream> // /usr/include/c++/4.6/sstream
int main(int argc, char** argv)
{
ros::init(argc,argv,"example1_a"); // nnode name
ros::NodeHandle n;
ros::Publisher chatter_pub = n.advertise<std_msgs::String>("message",1000);
ros::Rate rate(1);
int count = 0;
while(ros::ok())
{
std_msgs::String msg;
std::stringstream ss;
ss << "I am CAFFEE_LEEMAN"<< count ;
msg.data = ss.str();
ROS_INFO("%s",msg.data.c_str());
chatter_pub.publish(msg);
count++;
ros::spinOnce(); //NO call back , but ok. spinonce can execute following code after it ,
rate.sleep();
}
return 0;
}
- 订阅者
#include "ros/ros.h"
#include "std_msgs/String.h"
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("I heard [%s]",msg->data.c_str());
}
//String (string data)
//ConstPtr& 声明形参为引用传递时用法 包名::类名::ConstPtr&
int main(int argc, char** argv)
{
ros::init(argc, argv,"example1_b");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("message",1000,chatterCallback);
ros::spin();//到此处才会回掉!!
return 0;
}
编写package.xml (1)
cmake_minimum_required(VERSION 2.8.3)
project(ch2)
find_package(catkin REQUIRED COMPONENTS roscpp std_msgs)
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES ch2
# CATKIN_DEPENDS roscpp std_msgs
# DEPENDS system_lib
)
###########
## Build ##
###########
## Specify additional locations of header files
include_directories(include ${catkin_INCLUDE_DIRS})
## Declare a C++ executable
add_executable(ex1a src/ex1_a.cpp)
add_executable(ex1b src/ex1_b.cpp)
add_dependencies(ex1a ch2_generate_messages_cpp)
add_dependencies(ex1b ch2_generate_messages_cpp)
#此处的模板写法是add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${CATKIN_EXPORTED_TARGETS})
## Specify libraries to link a library or executable target against
target_link_libraries(ex1a ${catkin_LIBRARIES} )
target_link_libraries(ex1b ${catkin_LIBRARIES} )
package.xml(2)
cmake_minimum_required(VERSION 2.8.3)
project(ch2)
find_package(catkin REQUIRED COMPONENTS roscpp std_msgs)
#均位于share目录中的包
catkin_package(
INCLUDE_DIRS include
LIBRARIES ch2
CATKIN_DEPENDS roscpp std_msgs
DEPENDS system_lib
)
###########
## Build ##
###########
## Specify additional locations of header files
##include_directories(include ${catkin_INCLUDE_DIRS})
##注解该句,是因为catkin_package(..)已经包含了include
##使用catkin_cmake,默认路径是${CATKIN_PREFIX_PATH=/OPT/ROS/HYDOR/}
## ls /opt/ros/hydro
## bin etc lib include share setup.bahs ...
## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
add_executable(ex1a src/ex1_a.cpp)
add_executable(ex1b src/ex1_b.cpp)
#add_dependencies(ex1a ch2_generate_messages_cpp)
#add_dependencies(ex1b ch2_generate_messages_cpp)
##这两句可以注解是因为cakin_package(...)的原因
## Specify libraries to link a library or executable target against
target_link_libraries(ex1a ${catkin_LIBRARIES} )
target_link_libraries(ex1b ${catkin_LIBRARIES} )
##以上两个链接库,必须,否则链接时会报错。
话题列表
robot@ubuntu:~/dev/catkin_ws$ rosnode list
/example1_a //节点名由ros::init决定,与程序名无关
/example1_b
/rosout
/rostopic_50864_1503976194535
/teleop_turtle
robot@ubuntu:~/dev/catkin_ws$ rostopic list
/message //话题名,此处为绝对作用域,带/
/rosout
/rosout_agg
/turtle1/cmd_vel
- 使用自建数据消息类型msg
在src/ch2/下mkdir msg
<run_depend>message_runtime</run_depend>
cmake_minimum_required(VERSION 2.8.3)
project(ch2)
find_package(catkin REQUIRED COMPONENTS roscpp std_msgs message_generation)
add_message_files(FILES add.msg)
generate_messages(DEPENDENCIES std_msgs)
#generate_messages() must be called before catkin_package()顺序有要求!!!
catkin_package(
INCLUDE_DIRS include
LIBRARIES ch2
CATKIN_DEPENDS roscpp std_msgs
DEPENDS system_lib
)
###########
## Build ##
###########
## Specify additional locations of header files
#include_directories(include ${catkin_INCLUDE_DIRS})
## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
add_executable(ex1a src/ex1_a.cpp)
add_executable(ex1b src/ex1_b.cpp)
#add_dependencies(ex1a ch2_generate_messages_cpp)
#add_dependencies(ex1b ch2_generate_messages_cpp)
## Specify libraries to link a library or executable target against
target_link_libraries(ex1a ${catkin_LIBRARIES} )
target_link_libraries(ex1b ${catkin_LIBRARIES} )
编译
int32 B
int32 C
- 创建srv文件
新建srv文件目录 catkin_ws/src/ch2/
int32 B
int32 C
---
int32 SUM
- 为srv更改packge.xml(其实和修改msg时一样,现在不用改了)
<build_depend>message_generation</build_depend>
<run_depend>message_runtime</run_depend>
<run_depend>message_runtime</run_depend>
- 为srv更改cmakelist.txt,如下:
cmake_minimum_required(VERSION 2.8.3)
project(ch2)
find_package(catkin REQUIRED COMPONENTS
roscpp
std_msgs
message_generation #msg,srv必须
)
add_message_files(FILES add.msg)
add_service_files(FILES addsrv.srv) #srv 新加
generate_messages(DEPENDENCIES std_msgs) #srv msg 必须,相同
#generate_messages() must be called before catkin_package()
catkin_package(
INCLUDE_DIRS include
LIBRARIES ch2
CATKIN_DEPENDS roscpp std_msgs
DEPENDS system_lib
)
###########
## Build ##
###########
## Specify additional locations of header files
#include_directories(include ${catkin_INCLUDE_DIRS})
## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
add_executable(ex1a src/ex1_a.cpp)
add_executable(ex1b src/ex1_b.cpp)
#add_dependencies(ex1a ch2_generate_messages_cpp)
#add_dependencies(ex1b ch2_generate_messages_cpp)
## Specify libraries to link a library or executable target against
target_link_libraries(ex1a ${catkin_LIBRARIES} )
target_link_libraries(ex1b ${catkin_LIBRARIES} )
- 检查
rossrv show ch2/addsrv
不编译,也可以使用上面命令检查,但是catkin_make之后,会生成相应消息或者服务的头文件。
- 重点——消息和头文件的生成(编译后,路径在哪里呢?)
robot@ubuntu:~/dev/catkin_ws$ cd devel/
robot@ubuntu:~/dev/catkin_ws/devel$ ls
env.sh include setup.bash _setup_util.py share
etc lib setup.sh setup.zsh
robot@ubuntu:~/dev/catkin_ws/devel$ cd include/
robot@ubuntu:~/dev/catkin_ws/devel/include$ ls
ch2
robot@ubuntu:~/dev/catkin_ws/devel/include$ cd ch2/
robot@ubuntu:~/dev/catkin_ws/devel/include/ch2$ ls
add.h addsrv.h addsrvRequest.h addsrvResponse.h ###重点###阿达
- 使用自定义服务
touch addTwoIntsSrv.cpp
#include "ros/ros.h"
#include "add/AddTwoInts.h"
bool adds(add::AddTwoInts::Request &req,
add::AddTwoInts::Response &res)
{
res.sum = req.a + req.b;
ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
ROS_INFO("sending back response: [%ld]", (long int)res.sum);
return true;
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "add_two_ints_server");
ros::NodeHandle n;
ros::ServiceServer service = n.advertiseService("add_two_ints", adds);
ROS_INFO("Ready to add two ints.");
ros::spin();
return 0;
}
客户端
touch addTwoIntClt.cpp
#include "ros/ros.h"
#include "add/AddTwoInts.h"
#include <cstdlib>
int main(int argc, char **argv)
{
ros::init(argc, argv, "add_two_ints_client");
if (argc != 3)
{
ROS_INFO("usage: add_two_ints_client X Y");
return 1;
}
ros::NodeHandle n;
ros::ServiceClient client = n.serviceClient<add::AddTwoInts>("add_two_ints");
add::AddTwoInts srv;
srv.request.a = atoll(argv[1]);
srv.request.b = atoll(argv[2]);
if (client.call(srv))
{
ROS_INFO("Sum: %ld", (long int)srv.response.sum);
}
else
{
ROS_ERROR("Failed to call service add_two_ints");
return 1;
}
return 0;
}
此处使用服务消息的头文件和用法和自定义话题一样!!包名/服务文件名
cmakelists.txt同样需要注意先添加消息文件,再生成消息
- 使用话题发布自定义消息
在add/msg touch Num2.msg
int32 A
int32 B
int32 C
touch topictalker.cpp
#include "ros/ros.h"
#include "add/Num2.h"
int main(int argc, char **argv)
{
ros::init(argc, argv, "example3_a");
ros::NodeHandle n;
ros::Publisher pub = n.advertise<add::Num2>("addTwoIntTopic", 1000);
ros::Rate loop_rate(10);
while (ros::ok())
{
add::Num2 msg;
msg.A = 1;
msg.B = 2;
msg.C = 3;
pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
}
return 0;
}
touch topiclister.cpp
#include "ros/ros.h"
#include "add/Num2.h"
void messageCallback(const add::Num2::ConstPtr& msg)
{
ROS_INFO("I heard: [%d] [%d] [%d]", msg->A, msg->B, msg->C);
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "example3_b");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("addTwoIntTopic", 1000, messageCallback);
ros::spin();
return 0;
}
注意的是头文件的用法
add/Num2.msg 前面包名/后面自定义消息文件名
在Cmakelists.txt中切记要先add_message_files(FILES add.msg)
再generate_messages(DEPENDENCIES std_msgs)
___________________________python_________________________________
话题
talker.py
#!/usr/bin/env python
import rospy
from std_msgs.msg import String
# rospy.init_node(NAME, ...), it tells rospy the name of your node
# until rospy has this information, it cannot start communicating with the ROS Master.
# the name must be a base name, i.e. it cannot contain any slashes "/".
def talker():
pub = rospy.Publisher('chatter',String,queue_size=10)
rospy.init_node('talker',anonymous=True)
rate = rospy.Rate(10)
while not rospy.is_shutdown():
hello_str = "hello world%s" % rospy.get_time()
rospy.loginfo(hello_str)
rospy.logdebug(hello_str)
pub.publish(hello_str)
rate.sleep()
if __name__ == '__main__':
try:
talker()
except rospy.ROSInterruptException:
pass
listen.py
#!/usr/bin/env python
import rospy
from std_msgs.msg import String
def callback(data):
rospy.loginfo(rospy.get_caller_id() + "I heard %s ", data.data)
def listener():
rospy.init_node('listenner',anonymous=True)
rospy.Subscriber('chatter',String,callback)
rospy.spin()
#rospy.spin() simply keeps your node from exiting until the node has been shutdown.
#Unlike roscpp, rospy.spin() does not affect the subscriber callback functions, as those have their own threads.
if __name__ == '__main__':
listener()
服务
add_two_ints_server.py
#!/usr/bin/env python
from hellopy.srv import *
import rospy
def handle_add_two_ints(req):
print "Returning [%s + %s = %s]" % (req.a,req.b,(req.a+req.b))
return AddTwoIntsResponse(req.a+req.b)
def add_two_ints_server():
rospy.init_node('add_two_ints_server')
s = rospy.Service('add_two_ints',AddTwoInts,handle_add_two_ints)
print "Ready to add two ints"
rospy.spin()
if __name__ == '__main__':
add_two_ints_server()
add_two_ints_client.py
#!/usr/bin/env python
import rospy
from hellopy.srv import *
def add_two_ints_client(x,y):
rospy.wait_for_service('add_two_ints')
try:
add_two_ints = rospy.ServiceProxy('add_two_ints',AddTwoInts)
resp1 = add_two_ints(x,y)
return resp1.sum
except rospy.ServiceException, e:
print "Service call failed:%s" % e
def usage():
return "%s [x,y]" % sys.argv[0]
if __name__ == '__main__':
if len(sys.argv)== 3:
x = int(sys.argv[1])
y = int(sys.argv[2])
else:
print usage()
sys.exit(1)
print "Requesting %s + %s" % (x,y)
print"%s + %s = %s " % (x,y,add_two_ints_client(x,y))
python 如果自定的数据类型或者服务,也是需要编译的,如果是标准的话题或者数据格式,可以不编译
CMakeLists.txt
cmake_minimum_required(VERSION 2.8.3)
project(hellopy)
find_package(catkin REQUIRED COMPONENTS
geometry_msgs
roscpp
rospy
std_msgs
message_generation
)
## Generate messages in the 'msg' folder
add_message_files(
FILES
Num.msg)
## Generate services in the 'srv' folder
add_service_files(
FILES
AddTwoInts.srv)
generate_messages(
DEPENDENCIES
std_msgs
)
catkin_package(
INCLUDE_DIRS include
LIBRARIES hellopy
CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs message_runtime
DEPENDS system_lib
)
###########
## Build ##
###########
include_directories(
# include
${catkin_INCLUDE_DIRS}
)
# add_executable(${PROJECT_NAME}_node src/hellopy_node.cpp)
# target_link_libraries(${PROJECT_NAME}_node
# ${catkin_LIBRARIES}
# )