Course 2 ROS包结构
ROS文件组成
ROS由包含源代码,launch文件,配置文件,消息定义,数据和文档的包组成。一个包里面还可以通过denpendencies包含别的包的内容。
新建一个包的代码为:
> catkin_create_pkg package_name {dependencies}
一、介绍几个不同类型的文件:
1. package.xml
(前面包名,版本号,作者什么的比较简单,要注意最后用的依赖其他包的用法。)
<?xml version="1.0"?>
<package format="2">
<name>ros_package_template</name>
<version>0.1.0</version>
<description>A template for ROS packages.</description>
<maintainer email="pfankhauser@e…">Peter Fankhauser</maintainer>
<license>BSD</license>
<url type="website">https://github.com/ethz-asl/ros_best_pr…</url>
<author email="pfankhauser@ethz.ch">Peter Fankhauser</author>
<buildtool_depend>catkin</buildtool_depend>
<depend>roscpp</depend>
<depend>sensor_msgs</depend>
</package>
2. CMakeLists.txt
(需要用的CMake的版本,包的名字,需要用的包要在find_package里注明,指定生成导出信息:头文件地址和依赖的包的文件,指定头文件位置,声明执行文件,再次指定可执行文件的库。)
cmake_minimum_required(VERSION 2.8.3)
project(husky_highlevel_controller)
add_definitions(--std=c++11)
find_package(catkin REQUIRED
COMPONENTS roscpp sensor_msgs
)
catkin_package(
INCLUDE_DIRS include
# LIBRARIES
CATKIN_DEPENDS roscpp sensor_msgs
# DEPENDS
)
include_directories(include ${catkin_INCLUDE_DIRS})
add_executable(${PROJECT_NAME} src/${PROJECT_NAME}_node.cpp
src/HuskyHighlevelController.cpp)
target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES})
3. hello_world.cpp(Client的例子)
(首先初始化节点;然后定义句柄nodeHandle,句柄在roscpp内部提供了RAll方式启动和关闭,句柄还可以让你通过构造函数指定命名空间;ros::Rate是用来以一种设定的频率来运行循环的类;ros::ok()是用来判断节点是否一致运行的;ros::INFO()会打印消息;ros::spinOnce()通过回调来处理传入的消息)
#include <ros/ros.h>
int main(int argc, char** argv)
{
ros::init(argc, argv, "hello_world");
ros::NodeHandle nodeHandle;
ros::Rate loopRate(10);
unsigned int count = 0;
while (ros::ok()) {
ROS_INFO_STREAM("Hello World " << count);
ros::spinOnce();
loopRate.sleep();
count++;
}
return 0;
}
四种主要类型的句柄
* Default (public) node handle:
nh_ = ros::NodeHandle();
(/namespace/topic)
* Private node handle:
nh_private_ = ros::NodeHandle(“~”);
(/namespace/node/topic)
* Namespaced node handle:
nh_eth_ = ros::NodeHandle(“eth”);
(/namespace/eth/topic)
* Global node handle:
nh_global_ = ros::NodeHandle(“/”);
(不推荐使用全局句柄 /topic)
4. listener.cpp(Subscriber的例子)
(首先定义是订阅者,然后监听chatter节点,如果有消息则调用函数)
#include "ros/ros.h"
#include "std_msgs/String.h"
void chatterCallback(const std_msgs::String& msg)
{
ROS_INFO("I heard: [%s]", msg.data.c_str());
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "listener");
ros::NodeHandle nodeHandle;
ros::Subscriber subscriber =
nodeHandle.subscribe("chatter",10,chatterCallback);
ros::spin();
return 0;
}
5. talker.cpp(publisher的例子)
(首先定义自己是发布者,然后指定消息类型和话题,固定频率后,在函数中循环发出消息。)
#include <ros/ros.h>
#include <std_msgs/String.h>
int main(int argc, char **argv) {
ros::init(argc, argv, "talker");
ros::NodeHandle nh;
ros::Publisher chatterPublisher =
nh.advertise<std_msgs::String>("chatter", 1);
ros::Rate loopRate(10);
unsigned int count = 0;
while (ros::ok()) {
std_msgs::String message;
message.data = "hello world " + std::to_string(count);
ROS_INFO_STREAM(message.data);
chatterPublisher.publish(message);
ros::spinOnce();
loopRate.sleep();
count++;
}
return 0;
}
二、ROS参数服务器
节点使用参数服务器来存储或者取出参数;参数可以直接在launch文件中定义,也可以写在YAML文件中。
列出所有参数:
> rosparam list
获得参数的值:
> rosparam get parameter_name(命令行版)
nodeHandle.getParam(parameter_name, variable)(C++版)
设置参数的值:
> rosparam set parameter_name value
config.yaml
camera:
left:
name: left_camera
exposure: 1
right:
name: right_camera
exposure: 1.1
package.launch
<launch>
<node name="name" pkg="package" type="node_type">
<rosparam command="load"
file="$(find package)/config/config.yaml" />
</node>
</launch>
三、RViz
rviz是ROS官方的一款3D可视化工具,可扩展化。在rviz中常使用激光数据可视化显示、图像数据可视化显示。
启动rviz:
> rosrun rviz rviz