目录
- 自问自答v1
- 一、echo $ROS_PACKAGE_PATH 这句话是什么意思
- 二、source devel/setup.bash 这句话什么意思
- 三、shell 与 bash
- 四、$ 这个符号什么意思
- 五、ros 里 int main(int argc, char **argv) 怎么理解
- 六、ros工作空间里的文件夹都是放什么的
- 自问自答v2
- 一、添加srv、msg消息的时候怎么配置CMakeLists.txt 和 package.xml
- 二、怎么在源码中使用呢
- 三、ros中的回调函数的参数怎么理解
- 四、msg是Array Type类型的怎么用
- 五、roslaunch怎么用
自问自答v1
一、echo $ROS_PACKAGE_PATH 这句话是什么意思
echo 英文意思:回响; 回声; 回音; 映现; 暗示; 启示; 反响; 共鸣; 附和; 重复
在linux下的作用:就是文本输入,然后显示
#To make sure your workspace is properly overlayed by the setup script, make sure ROS_PACKAGE_PATH environment variable includes the directory you're in.
zyf@zyf-TM1707:~$ echo $ROS_PACKAGE_PATH
/home/zyf/chuankou/src:/home/zyf/catkin_ws/src:/opt/ros/melodic/share
答:显示ROS_PACKAGE_PATH 的路径内容,输出的文本可以看出有三个路径在里面
echo "int64 num" > msg/Num.msg
echo也可以向文件中写入数据。
二、source devel/setup.bash 这句话什么意思
用法:
source filename # filename必须是可执行的脚本文件
或者
. filename # 注意“.”号后面还有一个空格
区别
当shell脚本具有可执行权限时,用sh filename与./filename是没有区别的。
./filename是因为当前目录没有在PATH中,所以"."是用来表示当前目录的。
source filename读取脚本里面的语句依次在当前shell里面执行,没有建立新的子shell。那么脚本里面所有新建、改变变量的语句都会保存在当前shell里面。
答:测试可以知道source 和 . 都是运行一个二进制文件的 (.bash)
三、shell 与 bash
Shell俗称壳(用来区别于内核),是指“提供使用者使用界面”的软件,就是一个命令行解释器。
bash 是一个为GNU项目编写的Unix shell,也就是linux用的shell。
就是说,bash是一种shell
答:bahs是shell的一种,可以理解成 命令窗口 :terminal
四、$ 这个符号什么意思
答:$ 符号用在什么地方,使用在不同的地方,其所代表的定义也就不同。比如在bash里 $ 符号表示当前用户为普通用户;在bash脚本里。$开头表示变量。
五、ros 里 int main(int argc, char **argv) 怎么理解
答:c++中的理解是:第一个参数,int型的argc,为整型,用来统计程序运行时发送给main函数的命令行参数的个数
第二个参数,char*型的argv[],为字符串数组,用来存放指向的字符串参数的指针数组,每一个元素指向一个参数。
ros里用起来的意义是:argc 即 运行改节点时的输入参数个数,argv[] 参数字符数组,其中第0个参数是程序本身(包括路径)
六、ros工作空间里的文件夹都是放什么的
自问自答v2
一、添加srv、msg消息的时候怎么配置CMakeLists.txt 和 package.xml
官网:http://wiki.ros.org/ROS/Tutorials/CreatingMsgAndSrv ①其实以上两个文件已经备注好了,当要添加消息的时候,package.xml 需要添加 创建依赖和执行依赖
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
②在CMakeList.txt 中根据注释也可发现
find_package(catkin REQUIRED COMPONENTS
geometry_msgs
roscpp
std_msgs
turtlesim
message_generation
)
catkin_package(
...
CATKIN_DEPENDS message_runtime ...
...)
add_message_files(
FILES
Num.msg
)
generate_messages(
DEPENDENCIES
std_msgs
)
③测试一下
$ rossrv show <service type>
$ rosmsg show <service type>
二、怎么在源码中使用呢
①添加头文件 Num.h 在工作空间下->devel->include->(package_name)->Num.h
#include "(package_name)/Num.h"
②定义
package_name::Num msg;
三、ros中的回调函数的参数怎么理解
#include <ros/ros.h>
#include <std_msgs/String.h>
#include <sstream>
void Listener::callback(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("I heard: [%s]", msg->data.c_str());
std::stringstream ss;
ss << msg->data.c_str();
ss >> copy_data;
std::cout <<"copy_data is: " << copy_data <<"\n";
print_data2();
}
C++中值传递和引用传递的方式
C++的值传递(pass-by-value) 是从调用的地方把值复制一遍传给函数,这样做有两个问题,第一,需要将实参拷贝到形参处,形成实参的副本,有时间和空间的开销,若实参为结构体或者类的话,那么时空开销将会非常大;第二、函数中对实参副本的修改并不会影响到函数调用位置实参的值。
C++的引用传递(pass-by-reference),一方面,参数传递的是把实参的地址拷贝到形参,这样形参和实参对应的是同一块儿内存地址,那么对形参的修改自然会反映到实参上;另一方面,C++中指针或者引用只占4字节,所以时空开销也能接受。
& 的目的是引用,避免再了复制一个std::string
const 是为了限定它只读
const string s 的话还是要再复制一次岂不是很浪费,既然已经是只读了可以直接用
因为 C++ 规定引用不能为空,所以一个函数传进来引用你就可以直接用,而传进来指针你还需要判断指针是否为空
如果直接传值的话,对于对象就要新建一个临时对象——这个步骤需要调用复制构造函数,如果对象本身比较大的话就会造成很严重的资源浪费。而传引用就可以避免这一点——如果我们需要只读地访问一个对象的话使用常引用可以有效避免资源浪费。
四、msg是Array Type类型的怎么用
查看ros.wiki发现Array Type:
①std::
std::是个名称空间标识符,C++标准库中的函数或者对象都是在命名空间std中定义的,所以我们要使用标准库中的函数或者对象都要用std来限定。
②vector<>
vector 是使用new创建动态数组的替代品,也是使用new和delete来管理内存,但这工作是自动完成的。
- 初始化:
std::vector<int> nVec; // 空对象
std::vector<int> nVec(5,-1); // 创建了一个包含5个元素且值为-1的vector
std::vector<std::string> strVec{"a", "b", "c"}; // 列表初始化
- 赋值与输出
std::vector<int> nVec;
for(int i = 0; i < 5; ++i)
nVec.push_back(i); // 压入元素
for(size_t i = 0; i < nVec.size(); ++i)
std::cout << nVec[i] << std::endl; // 输出元素
五、roslaunch怎么用
- Launch文件是ROS提供的,可以同时运行多个nodes的文件。Launch文件以一种特殊的XML格式编写,在ROS packages中使用广泛。
- 运行$ roslaunch package_name launch_file_name
- 新建launch文件
可以参考 https://www.jianshu.com/p/13efab3f67e0
官 网 http://wiki.ros.org/roslaunch/XML/param - 补充:
arg标签 在launch文件中,要声明一个参数的存在,我们使用arg元素:
<arg name="arg-name" />
声明里面只有一个 name 是起不上什么作用的,这就像是你在程序中定义了一个 int 类型的变量,但 是你并没有使用它一样。(你至少还需要给 arg 元素分配 default 属性或 value 属性)
①给arg赋值
在launch文件中使用的每一个argument必须给它分配一个 value(赋值)。有以下两种实现方法:
在命令行中你可以这样做:给 roslaunch 提供一个 value :
$ roslaunch package-name launch-file-name arg-name:=arg-value
另外,在launch文件中,你可以提供一个 value(赋值) 作为 arg 声明的一部分,使用下面的两种语法之一就可以:
<arg name="arg-name" default="arg-value" />
<arg name="arg-name" value="arg-value" />
这两种语法的唯一不同是:命令行可以覆盖default的值,但是不能覆盖 value 。在例子launch文件 中,use_sim3 节点的 default 值为 0,所以它可以通过命令行改变值,就像下面这样:
$ roslaunch agitr triplesim.launch use_sim3:=1
如果我们修改了这个例子launch文件:使用value替换default。那么上面这个命令执行的时候会出 现错误,因为使用 value属性 配置的argument的值是不允许改变的。
②获取argument的数值
$(arg arg-name)
$() 这个符号出现的任何地方,roslaunch命令都将会把它替换成给定argument 的值(value)。
③关于argument的继承
在argument的传递上有一个限制,就是argument不能传递给 include 元素里包含的子launch文件 使用。这个问题非常重要,因为这个 argument 就像是一个局部变量,它不能被包含的launch文件 所 “继承” 。
解决这个问题的方法:在 include 元素中插入 arg 元素作为 include 元素的子类(children),就像是这样:
<include file="path-to-launch-file">
<arg name="arg-name" value="arg-value"/>
. . .
</include>
注意,这里的 arg 元素不同于我们已经知道的 arg 声明,在 inchude 标签内的arguments是给包含 (included) 的launch文件提供的arguments,不是为本launch文件提供的。
一种常见的情况是,被包含(included)的launch文件和本launch文件会有共同的参数。在这种情况下,我们希望这些值(values)永远不变。像这样的元素,在这两个地方使用相同的argument name (参数名),要这样做:
<arg name="arg-name" value="$(arg arg-name)" />
在这种情况下,第一个 arg-name 和往常一样。第二个 arg-name 是launch文件中提供的。结果是,这两个launch文件中给定的argument具有相同的值(value)。
④argument和parameter有区别
尽管术语argument和parameter在许多计算机环境中稍微可以互换使用,它们的含义在ROS中有很大的不同。Parameters(参数)在一个运行的ROS系统中是变量(values),它被存储在parameter服务器中,活动(或者叫:运行)的节点通过ros::param::get()函数访问它,并且用户可以通过 rosparam 命令行工具使用它。相比之下,arguments只有在launch文件里合法,它们的值不是直接提供给节点。
总结一下