# 6.5 param in roscpp
## 6.5.1 Parameter Server
嚴格來說,param并不能稱作一種通信方式,因為它往往只是用來存儲一些靜態的設置,而不是動態變化的。所以關于param的操作非常輕巧,非常簡單。
關于param的API,roscpp為我們提供了兩套,一套是放在`ros::param`namespace下,另一套是在`ros::NodeHandle`下,這兩套API的操作完全一樣,用哪一個取決于你的習慣。
## 6.5.2 param_demo
我們來看看在C++中如何進行param_demo的操作,`param_demo/param.cpp`文件,內容包括:
```cpp
#include<ros/ros.h>
int main(int argc, char **argv){
ros::init(argc, argv, "param_demo");
ros::NodeHandle nh;
int parameter1, parameter2, parameter3, parameter4, parameter5;
//Get Param的三種方法
//① ros::param::get()獲取參數“param1”的value,寫入到parameter1上
bool ifget1 = ros::param::get("param1", parameter1);
//② ros::NodeHandle::getParam()獲取參數,與①作用相同
bool ifget2 = nh.getParam("param2",parameter2);
//③ ros::NodeHandle::param()類似于①和②
//但如果get不到指定的param,它可以給param指定一個默認值(如33333)
nh.param("param3", parameter3, 33333);
if(ifget1) //param是否取得
...
//Set Param
//① ros::param::set()設置參數
parameter4 = 4;
ros::param::set("param4", parameter4);
//② ros::NodeHandle::setParam()設置參數
parameter5 = 5;
nh.setParam("param5",parameter5);
//Check Param
//① ros::NodeHandle::hasParam()
bool ifparam5 = nh.hasParam("param5");
//② ros::param::has()
bool ifparam6 = ros::param::has("param6");
//Delete Param
//① ros::NodeHandle::deleteParam()
bool ifdeleted5 = nh.deleteParam("param5");
//② ros::param::del()
bool ifdeleted6 = ros::param::del("param6");
...
}
```
以上是roscpp中對param進行增刪改查所有操作的方法,非常直觀。
## 6.5.3 param_demo中的launch文件
實際項目中我們對參數進行設置,尤其是添加參數,一般都不是在程序中,而是在launch文件中。因為launch文件可以方便的修改參數,而寫成代碼之后,修改參數必須重新編譯。
因此我們會在launch文件中將param都定義好,比如這個demo正確的打開方式應該是`roslaunch param_demo param_demo_cpp.launch`
`param_demo/launch/param_demo_cpp.launch`內容為:
```xml
<launch>
<!--param參數配置-->
<param name="param1" value="1" />
<param name="param2" value="2" />
<!--rosparam參數配置-->
<rosparam>
param3: 3
param4: 4
param5: 5
</rosparam>
<!--以上寫法將參數轉成YAML文件加載,注意param前面必須為空格,不能用Tab,否則YAML解析錯誤-->
<!--rosparam file="$(find robot_sim_demo)/config/xbot2_control.yaml" command="load" /-->
<node pkg="param_demo" type="param_demo" name="param_demo" output="screen" />
</launch>
```
通過<param>和<rosparam>兩個標簽我們設置好了5個param,從而在之前的代碼中進行增刪改查的操作。
## 6.5.3 命名空間對param的影響
在實際的項目中,實例化句柄時,經常會看到兩種不同的寫法
ros::NodeHandle n;
ros::NodeHandle nh("~");`
這兩種寫法有什么不同呢?以本教學報的name_demo為例。在本節launch文件夾的demo.launch定義兩個參數,一個全局serial 他的數值是5,一個是局部的serial,他的數值是10.
```xml
<launch>
<!--全局參數serial-->
<param name="serial" value="5" />
<node name="name_demo" pkg="name_demo" type="name_demo"
output="screen">
<!--局部參數serial-->
<param name="serial" value="10" />
</node>
</launch>
```
在name_demo.cpp中,我們分別嘗試了,利用全局命名空間句柄提取全局的param和局部的param,以及在局部命名空間下的句柄提取全局的param和局部的param,詳細的代碼如下:
```cpp
#include <ros/ros.h>
int main(int argc, char* argv[])
{
int serial_number = -1;//serial_number初始化
ros::init(argc, argv, "name_demo");//node初始化
/*創建命名空間*/
//n 是全局命名空間
ros::NodeHandle n;
//nh 是局部命名空間
ros::NodeHandle nh("~");
/*全局命名空間下的Param*/
ROS_INFO("global namespace");
//提取全局命名空間下的參數serial
n.getParam("serial", serial_number);
ROS_INFO("global_Serial was %d", serial_number);
//提取局部命名空間下的參數serial
n.getParam("name_demo/serial", serial_number);//在全局命名空間下,要提取局部命名空間下的參數,需要添加node name
ROS_INFO("global_to_local_Serial was %d", serial_number);
/*局部命名空間下的Param*/
ROS_INFO("local namespace");
//提取局部命名空間下的參數serial
nh.getParam("serial", serial_number);
ROS_INFO("local_Serial was %d", serial_number);
//提取全局命名空間下的參數serial
nh.getParam("/serial", serial_number);//在局部命名空間下,要提取全局命名空間下的參數,需要添加“/”
ROS_INFO("local_to_global_Serial was %d", serial_number);
ros::spin();
return 0;
}
```
最后的結果
```xml
[ INFO] [1525095241.802257811]: global namespace
[ INFO] [1525095241.803512501]: global_Serial was 5
[ INFO] [1525095241.804515959]: global_to_local_Serial was 10
[ INFO] [1525095241.804550167]: local namespace
[ INFO] [1525095241.805126562]: local_Serial was 10
[ INFO] [1525095241.806137701]: local_to_global_Serial was 5
```
- 前言
- 第一章 ROS簡介
- 機器人時代的到來
- ROS發展歷程
- 什么是ROS
- 安裝ROS
- 安裝ROS-Academy-for-Beginners教學包
- 二進制與源碼包
- 安裝RoboWare Studio
- 單元測試一
- 第二章 ROS文件系統
- Catkin編譯系統
- Catkin工作空間
- Package軟件包
- CMakeLists.txt
- package.xml
- Metapacakge軟件元包
- 其他常見文件類型
- 單元測試二
- 第三章 ROS通信架構(一)
- Node & Master
- Launch文件
- Topic
- Msg
- 常見msg類型
- 單元測試三
- 第四章 ROS通信架構(二)
- Service
- Srv
- Parameter server
- Action
- 常見srv類型
- 常見action類型
- 單元測試四
- 第五章 常用工具
- Gazebo
- RViz
- Rqt
- Rosbag
- Rosbridge
- moveit!
- 單元測試五
- 第六章 roscpp
- Client Library與roscpp
- 節點初始、關閉與NodeHandle
- Topic in roscpp
- Service in roscpp
- Param in roscpp
- 時鐘
- 日志與異常
- 第七章 rospy
- Rospy與主要接口
- Topic in rospy
- Service in rospy
- Param與Time
- 第八章 TF與URDF
- 認識TF
- TF消息
- tf in c++
- tf in python
- 統一機器人描述格式
- 附錄:TF數學基礎
- 三維空間剛體運動---旋轉矩陣
- 三維空間剛體運動---歐拉角
- 三維空間剛體運動---四元數
- 第九章 SLAM
- 地圖
- Gmapping
- Karto
- Hector
- 第十章 Navigation
- Navigation Stack
- move_base
- costmap
- Map_server & Amcl
- 附錄:Navigation工具包說明
- amcl
- local_base_planner
- carrot_planner
- clear_costmap_recovery
- costmap_2d
- dwa_local_planner
- fake_localization
- global_planner
- map_server
- move_base_msg
- move_base
- move_slow_and_clear
- navfn
- nav_core
- robot_pose_ekf
- rotate_recovery