1. 创建工作空间并初始化
mkdir -p create_own_wkspc/src
cd create_own_wkspc
catkin build
2. 创建pkg,导入需要使用的依赖
在工作空间内的/src文件夹中创建pkg并导入依赖
cd src
catkin_create_pkg create_own_pkg roscpp std_msgs # roscpp和std_msgs是需要用到的依赖
3. 创建源文件
cd create_own_pkg
ls # 显示内容为CMakeLists.txt include package.xml src
在pkg产生的src的文件夹里创建需要的源文件(代码)
4. Exercise 1
初始化ros
//start node
ros::init(argc, argv, "SupeROS"); // 是 ROS 初始化函数的调用,用于初始化 ROS 系统。
// 它接受命令行参数 argc 和 argv,以及一个节点名称 "supeROS"
// $$节点名称是这个代码文件的名称吗?$$
//create variable for node
ros::NodeHandle n; // 创建了一个 ROS 节点句柄(Node Handle),它是与 ROS 系统进行通信的主要接口。
//通过使用节点句柄,你可以创建发布者、订阅者和服务等 ROS 组件,以及与其他节点进行通信。
...
//1- Declare publishers (employees) ///... TO BE COMPLETED ...///
ros::Publisher MrFish = nh.advertise<std_msgs::String>("/fish", 10);
ros::Publisher MrVeggies = nh.advertise<std_msgs::String>("/viggies", 10);
ros::Publisher MrFruits = nh.advertise<std_msgs::String>("/fruits", 10);
ros::Publisher
是发布者的类定义。MrFish..
是你给发布者起的名称,你可以自定义名称。nh.advertise<std_msgs::String>("/fish", 10)
是调用节点句柄nh
的advertise()
函数来创建发布者 ->std_msgs::String
是要发布的消息类型,"/fish"
是你要发布到的话题名称,10
是发布者的消息队列大小。
整体代码
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>
int main(int argc, char **argv)
{
//start node
ros::init(argc, argv, "SupeROS");
//create variable for node
ros::NodeHandle n;
//1- Declare publishers (employees) ///... TO BE COMPLETED ...///
ros::Publisher MrFish = nh.advertise<std_msgs::String>("fish", 100);
ros::Publisher MrVeggies = nh.advertise<std_msgs::String>("veggies", 100;
ros::Publisher MrFruits = nh.advertise<std_msgs::String>("fruit", 100);
ros::Rate loop_rate(10); // 10s wait in every loop
int count = 0;
while (ros::ok())
{
// 2- Declare msg for publishing data (point 4 might be helpful)
///... TO BE COMPLETED ...///
std_msgs::String msg_fisher;
std_msgs::String msg_veggies;
std_msgs::String msg_fruits;
// 3- Define possible options for food ///... TO BE COMPLETED ...///
std::vector<std::string> fisher_options = { "tuna", "salmon", "shark" };
std::vector<std::string> veggies_options = { "onion", "potatoes", "carrots"};
std::vector<std::string> fruit_options = { "bananas", "apples","grapes"};
//4- Store current option
///... TO BE COMPLETED ...///
if (count == 3){count = 0;} //reset counter if longer than amount of options
// 当count为3时重新设置为1
msg_fisher.data = fisher_options[count];
msg_veggies.data = veggies_options[count];
msg_fruits.data = fruits_options[count];
//5- Publish msg_X for all food types $$publisher -> msg$$
//... TO BE COMPLETED ...///
MrFish.publish(msg_fisher);
MrVeggies.publish(msg_veggies);
MrFruits.publish(msg_fruits);
ros::spinOnce(); // 用于接收所有信息
loop_rate.sleep();
++count;
}
return 0;
5. Exercise 2
#include "ros/ros.h"
#include "std_msgs/String.h"
//callback for customer 1
void customerCallback1(const std_msgs::String& msg){
if (msg == "carrots")
{
//print in command window
ROS_INFO("I purchased %s!", msg->data.c_str());
}
}
//callback for customer 2
void customerCallback2(const std_msgs::String& msg){
if (msg == "tuna")
{
//print in command window
ROS_INFO("I purchased %s!", msg->data.c_str());
}
}
//main function
int main(int argc, char **argv)
{
ros::init(argc, argv, "Clients");
ros::NodeHandle nh;
ros::Subscriber customer1_sub = nh.subscribe("veggies", 100, customerCallback1);
ros::Subscriber customer2_sub = nh.subscribe("fish", 100, customerCallback2);
ros::spin();
return 0;
}
6. 编译运行两文件,使得之间产生交流
在两个pkg的CMakeLists中分别添加语句
add_executable(exercise_2 src/exercise_2.cpp) # exercise_2为源文件名称
target_link_libraries(exercise_2 ${catkin_LIBRARIES})
add_dependencies(exercise_2 ${catkin_EXPORTED_TARGETS}) # 目前看起来可加可不加??
进入工作空间目录并编译
catkin_make
成功之后在一个终端中运行
roscore
然后新建两个终端(ctrl+shift+E/O: 垂直/水平分割终端 ),分别运行代码,即可实现交流
source ./devel/setup.bash
rosrun 包名 C++节点