**菜鸡错误之路**
程序写完之后要改的东西
CMakelist.txt文件
add_executable(hello_vscode_c src/hello_vscode_c.cpp)
修改两处
- src/后面的文件名字,要对应着你写的cpp的文件名字。
- 前面的映射文件名字(我随便叫的,哈哈),反正后面执行程序就不用输那一堆cpp文件的名字,直输入的就是你命名的那个名字。
target_link_libraries(hello_vscode_c
${catkin_LIBRARIES}
)
这里改的也就是和你上面起的那个名字对应就OK了。
Python文件写完之后要进行两步工作
- 赋予Python 文件可执行权限
chmod +x 你Python文件的名字
- CMakeList文件中将下面代码注释取消,并将scripts中的.py文件改为你文件的名字。
catkin_install_python(PROGRAMS
scripts/hello_vscode_p.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
Ros创建简单的cpp文件编译不通过
出现的问题如下图所示
通过将CmakeList.txt文件中的std_msg更改为std_msgs后编译成功。
Ros创建Python文件遇到问题
在用Python写的时候也报了错误
解决办法就是ennnnn,下面的方法
在Python文件前面加上下面这两句,顺序不能错。
#!/usr/bin/env python
#-*- coding: UTF-8 -*-
vocode的使用方法,赞!
参考的是这个网站的教学,我也是跟着学习记录一下。
http://www.autolabor.com.cn/book/ROSTutorials/chapter1/14-ros-ji-cheng-kai-fa-huan-jing-da-jian/142-an-zhuang-vscode.html
vocodecatkin_make:build 配置
进入vscode之后,按Ctrl shift B 点击:catkin_make:build后面的小齿轮,将下方的代码复制进去。
{
// 有关 tasks.json 格式的文档,请参见
// https://go.microsoft.com/fwlink/?LinkId=733558
"version": "2.0.0",
"tasks": [
{
"label": "catkin_make:debug", //代表提示的描述性信息
"type": "shell", //可以选择shell或者process,如果是shell代码是在shell里面运行一个命令,如果是process代表作为一个进程来运行
"command": "catkin_make",//这个是我们需要运行的命令
"args": [],//如果需要在命令后面加一些后缀,可以写在这里,比如-DCATKIN_WHITELIST_PACKAGES=“pac1;pac2”
"group": {"kind":"build","isDefault":true},
"presentation": {
"reveal": "always"//可选always或者silence,代表是否输出信息
},
"problemMatcher": "$msCompile"
}
]
}
vscode的代码提示功能
要在vocode项目下的c_cpp_properties.json文件中配置
"name": "ROS",
"intelliSenseMode": "gcc-x64",
"compilerPath": "/usr/bin/gcc",
"cStandard": "gnu11",
"cppStandard": "c++17"
改的地方只有最后一个,将最后一项改为 cppStandard:“c++17”
vscode 打印中文乱码
在c程序的前面加上这两句话的其中一句就OK了。
setlocale(LC_CTYPE, "zh_CN.utf8");
setlocale(LC_ALL, "");
c++写publisher
老师讲的很仔细,我就把他的代码抄过来了,以后写的时候看看思路。还有好多的注释。
http://www.autolabor.com.cn/book/ROSTutorials/di-2-zhang-ros-jia-gou-she-ji/22hua-ti-tong-xin/212-hua-ti-tong-xin-zhi-c-shi-xian.html
/*
需求: 实现基本的话题通信,一方发布数据,一方接收数据,
实现的关键点:
1.发送方
2.接收方
3.数据(此处为普通文本)
PS: 二者需要设置相同的话题
消息发布方:
循环发布信息:HelloWorld 后缀数字编号
实现流程:
1.包含头文件
2.初始化 ROS 节点:命名(唯一)
3.实例化 ROS 句柄
4.实例化 发布者 对象
5.组织被发布的数据,并编写逻辑发布数据
*/
// 1.包含头文件
#include "ros/ros.h"
#include "std_msgs/String.h" //普通文本类型的消息
#include <sstream>
int main(int argc, char *argv[])
{
//设置编码
setlocale(LC_ALL,"");
//2.初始化 ROS 节点:命名(唯一)
// 参数1和参数2 后期为节点传值会使用
// 参数3 是节点名称,是一个标识符,需要保证运行后,在 ROS 网络拓扑中唯一
ros::init(argc,argv,"talker");
//3.实例化 ROS 句柄
ros::NodeHandle nh;//该类封装了 ROS 中的一些常用功能
//4.实例化 发布者 对象
//泛型: 发布的消息类型
//参数1: 要发布到的话题
//参数2: 队列中最大保存的消息数,超出此阀值时,先进的先销毁(时间早的先销毁)
ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",10);
//5.组织被发布的数据,并编写逻辑发布数据
//数据(动态组织)
std_msgs::String msg;
// msg.data = "你好啊!!!";
std::string msg_front = "Hello 你好!"; //消息前缀
int count = 0; //消息计数器
//逻辑(一秒10次)
ros::Rate r(1);
//节点不死
while (ros::ok())
{
//使用 stringstream 拼接字符串与编号
std::stringstream ss;
ss << msg_front << count;
msg.data = ss.str();
//发布消息
pub.publish(msg);
//加入调试,打印发送的消息
ROS_INFO("发送的消息:%s",msg.data.c_str());
//根据前面制定的发送频率自动休眠 休眠时间 = 1/频率;
r.sleep();
count++;//循环结束前,让 count 自增
//暂无应用
ros::spinOnce();
}
return 0;
}
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>
int main(int argc ,char *argv[])
{
setlocale(LC_ALL,"");
ros::init(argc,argv,"talker");
ros::NodeHandle nh;
ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",10);
std_msgs::String msg;
ros::Rate rate(1);
int count = 0;
while (ros::ok())
{
count++;
std::stringstream ss;
ss<<"hello--->"<<count;
msg.data = ss.str();
pub.publish(msg);
ROS_INFO("发布的数据是:%s",ss.str().c_str());
rate.sleep();
ros::spinOnce();
}
return 0;
}
不会c++, 自己做下记录,熟悉一下程序书写结构*******,
之前学过一丢丢,要开始认真学了,可是C也还没熟悉。
ros::spinOnce();
这一句是
- 当spinOnce函数被调用时,spinOnce就会调用回调函数队列中第一个callback函数,此时callback函数被执行。
- spinOnce函数执行一次后,接着执行下面的语句。不像spin函数,进入到自己的内部循环,不往下执行。
- 等到下次spinOnce函数又被调用时,回调函数队列中第二个callback函数就会被调用,以此类推。
大佬讲的很仔细
自定义msg信息
首先在与src,scripts文件夹同级的目录下创建msg文件夹,然后在再该文件夹下创建msg文件,对于文件中数据类型的定义一般有这几种。
int8, int16, int32, int64 (或者无符号类型: uint*)
float32, float64
string
time, duration
other msg files
variable-length array[] and fixed-length array[C]
根据网站老师的案例讲解,写入这三个数据。
string name
uint16 age
float64 height
写完之后要修改一些列的文件,首先是在package.xml中添加这两行信息
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
然后再配置CMakeLists.txt文件,
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
add_message_files(
FILES
Person.msg
)
generate_messages(
DEPENDENCIES
std_msgs
)
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES demo02_talker_listener
CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
# DEPENDS system_lib
)
这一系列修改完毕之后,编译一下。
编写对应的talker和listener程序,两者对应的节点名一定要写对,不然无法通讯。
发送者:
#include "ros/ros.h"
#include "hello_vscode/Person.h"
int main(int argc ,char *argv[])
{
setlocale(LC_ALL,"");
ros::init(argc,argv,"talker_person");
ros::NodeHandle nh;
ros::Publisher pub = nh.advertise<hello_vscode::Person>("chatter",1000);
hello_vscode::Person p;
p.name = "lihua";
p.age = 200;
p.height = 1.46;
ros::Rate rate(1);
while (ros::ok())
{
pub.publish(p);
ROS_INFO("我叫:%s,今年:%d岁,高:%.2f米",p.name.c_str(),p.age,p.height);
rate.sleep();
ros::spinOnce();
}
return 0;
}
订阅者:
#include "ros/ros.h"
#include "hello_vscode/Person.h"
void doPerson(const hello_vscode::Person::ConstPtr& person_p){
ROS_INFO("订阅人的信息:%s,%d,%.2f",person_p->name.c_str(),person_p->age,person_p->height);
}
int main(int argc,char * argv[])
{
setlocale(LC_ALL,"");
ros::init(argc,argv,"listener_person");
ros::NodeHandle nh;
ros::Subscriber sub = nh.subscribe<hello_vscode::Person>("chatter",10,doPerson);
ros::spin();
return 0;
}