【ROS学习】ROS param 的使用

参数服务器 Parammeter Server
参数服务器维护的是一个字典,里面存储的是key、value,每一个key对应一个value。

一、rosparam 命令行操作

  1. 列出当前的所有参数:
rosparam list
  1. 显示某个参数的值
rosparam get param_key
  1. 设置某个参数的值
rosparam set param_key param_value
  1. 保存参数到文件
rosparam dump file_name
  1. 从文件读取参数
rosparam load file_name
注意这里的文件必须是YAML格式:

YAML格式举例:
name:‘ZhangSan’
age:20
gender:‘M’
score:{Chinese:80, Math:90}
score_history:[85,82,88,90]
  1. 删除某个参数
rosparam delete param_key

二、launch 文件载入param

  1. 通过param 标签设置参数的值
<launch>
	<param name="publish_frequency" value="20.0"/>
</launch>
  1. 通过加载yaml文件来设置param:
    下面这句指令也就是执行了 load 命令来实现装载文件的命令。
<launch>
	<!-- 把关节控制的配置信息读取到参数服务器 -->
	<rosparam file="$(find robot_sim_demo)/param/xbot-u_control.yaml" command="load"/>
</launch>
  1. 加载URDF 文件
    下面这句指令是 xacro.py 执行了 robot.xacro 之后输出的结果作为值赋给 robot_description。
<launch>
	<!-- URDF and TF support -->
  <param name="robot_description" command="$(find xacro)/xacro.py $(find robot_sim_demo)/urdf/robot.xacro" />
</launch>

launch 文件操作param 示例:

<launch>
	<!--param参数配置-->
	<param name="param1" value="1" />
	<param name="param2" value="2" />
	<!--param name="table_description" command="$(find xacro)/xacro.py $(find gazebo_worlds)/objects/table.urdf.xacro" /-->
	<!--rosparam参数配置-->
	<rosparam>   
        param3: 3
        param4: 4
        param5: 5
    </rosparam>
	<!--以上写法将参数转成YAML文件加载,注意param前面必须为空格,不能用Tab,否则YAML解析错误-->
	<!--rosparam file="$(find robot_sim_demo)/config/xbot-u_control.yaml" command="load" /-->
	<node pkg="param_demo" type="param_demo" name="param_demo" output="screen" >
	</node>
</launch>

三、c++ 中操作 param

#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);//parameter3 = nh.param("param3", 33333); //这两种方式都可以获取参数
		
	if(ifget1)
		ROS_INFO("Get param1 = %d", parameter1);
	else
		ROS_WARN("Didn't retrieve param1");
	if(ifget2)
		ROS_INFO("Get param2 = %d", parameter2);
	else
		ROS_WARN("Didn't retrieve param2");
	if(nh.hasParam("param3"))
		ROS_INFO("Get param3 = %d", parameter3);
	else
		ROS_WARN("Didn't retrieve param3");


    //Set Param的两种方法
	//① ros::param::set()设置参数
	parameter4 = 4;
	ros::param::set("param4", parameter4);

	//② ros::NodeHandle::setParam()设置参数
	parameter5 = 5;
	nh.setParam("param5",parameter5);
	
	ROS_INFO("Param4 is set to be %d", parameter4);
	ROS_INFO("Param5 is set to be %d", parameter5);


	//Check Param的两种方法
	//① ros::NodeHandle::hasParam()
	bool ifparam5 = nh.hasParam("param5");

	//② ros::param::has()
	bool ifparam6 = ros::param::has("param6");

	if(ifparam5) 
		ROS_INFO("Param5 exists");
	else
		ROS_INFO("Param5 doesn't exist");
	if(ifparam6) 
		ROS_INFO("Param6 exists");
	else
		ROS_INFO("Param6 doesn't exist");


	//Delete Param的两种方法
	//① ros::NodeHandle::deleteParam()
	bool ifdeleted5 = nh.deleteParam("param5");

	//② ros::param::del()
	bool ifdeleted6 = ros::param::del("param6");
	

	if(ifdeleted5)
		ROS_INFO("Param5 deleted");
	else
		ROS_INFO("Param5 not deleted");
	if(ifdeleted6)
		ROS_INFO("Param6 deleted");
	else
		ROS_INFO("Param6 not deleted");


	ros::Rate rate(0.3);
	while(ros::ok()){
		int parameter = 0;
		
		ROS_INFO("=============Loop==============");
		//roscpp中尚未有ros::param::getallparams()之类的方法
		if(ros::param::get("param1", parameter))
			ROS_INFO("parameter param1 = %d", parameter);
		if(ros::param::get("param2", parameter))
			ROS_INFO("parameter param2 = %d", parameter);
		if(ros::param::get("param3", parameter))
			ROS_INFO("parameter param3 = %d", parameter);
		if(ros::param::get("param4", parameter))
			ROS_INFO("parameter param4 = %d", parameter);
		if(ros::param::get("param5", parameter))
			ROS_INFO("parameter param5 = %d", parameter);
		if(ros::param::get("param6", parameter))
			ROS_INFO("parameter param6 = %d", parameter);
		rate.sleep();
	}
}

按照这样的配置运行launch文件,输出结果为:

[ INFO] [1599227480.007106576]: Get param1 = 1
[ INFO] [1599227480.007183637]: Get param2 = 2
[ INFO] [1599227480.008421688]: Get param3 = 3
[ INFO] [1599227480.013664463]: Param4 is set to be 4
[ INFO] [1599227480.013728307]: Param5 is set to be 5
[ INFO] [1599227480.016448700]: Param5 exists
[ INFO] [1599227480.016485628]: Param6 doesn't exist
[ INFO] [1599227480.018160277]: Param5 deleted
[ INFO] [1599227480.018213034]: Param6 not deleted
[ INFO] [1599227480.018256838]: =============Loop==============
[ INFO] [1599227480.019019334]: parameter param1 = 1
[ INFO] [1599227480.019704553]: parameter param2 = 2
[ INFO] [1599227480.020431854]: parameter param3 = 3
[ INFO] [1599227480.021171333]: parameter param4 = 4
[ INFO] [1599227483.351733159]: =============Loop==============
[ INFO] [1599227483.354448047]: parameter param1 = 1
[ INFO] [1599227483.355546242]: parameter param2 = 2
[ INFO] [1599227483.356730625]: parameter param3 = 3
[ INFO] [1599227483.357654706]: parameter param4 = 4
.......

四、python 中操作 param

#!/usr/bin/env python
# coding:utf-8

import rospy

def param_demo():
    rospy.init_node("param_demo")
    rate = rospy.Rate(1)
    while(not rospy.is_shutdown()):
        #get param
        parameter1 = rospy.get_param("/param1")
        parameter2 = rospy.get_param("/param2", default=222)
        rospy.loginfo('Get param1 = %d', parameter1)
        rospy.loginfo('Get param2 = %d', parameter2)

        #delete param
        rospy.delete_param('/param2')

        #set param
        rospy.set_param('/param2',2)
        
        #check param
        ifparam3 = rospy.has_param('/param3')
        if(ifparam3):
            rospy.loginfo('/param3 exists')
        else:
            rospy.loginfo('/param3 does not exist')

        #get all param names
        params = rospy.get_param_names()
        rospy.loginfo('param list: %s', params)

        rate.sleep()

if __name__=="__main__":
    param_demo()

运行这个python脚本文件输出结果为:

[INFO] [1599227816.193803]: Get param1 = 1
[INFO] [1599227816.194120]: Get param2 = 2
[INFO] [1599227816.198019]: /param3 exists
[INFO] [1599227816.199841]: param list: ['/roslaunch/uris/host_wong_inspiron_3558__37695', '/rosversion', '/run_id', '/param5', '/param4', '/param3', '/param2', '/param1', '/rosdistro']
[INFO] [1599227817.197727]: Get param1 = 1
[INFO] [1599227817.199030]: Get param2 = 2
[INFO] [1599227817.208759]: /param3 exists
[INFO] [1599227817.211776]: param list: ['/roslaunch/uris/host_wong_inspiron_3558__37695', '/rosversion', '/run_id', '/param5', '/param4', '/param3', '/param2', '/param1', '/rosdistro']
........

五、操作 param 时注意命名空间

在 c++ 操作参数的时候,我们经常会看到
ros::NodeHandle nh;ros::NodeHandle nh("~"); 两种用法。
主要是全局命名空间和局部命名空间的不同。
ros::NodeHandle nh; 是 全局命名空间,
ros::NodeHandle nh("~"); 是 局部命名空间。

<launch>
	<!-- 全局的 test_param -->
	<param name="param1" value="1" />
	<param name="param2" value="2" />
	
	<node pkg="param_demo" type="param_demo" name="param_demo" output="screen" >
		<!-- 局部的 test_param -->
		<param name="param3" value="3" />
		<param name="param4" value="4" />
	</node>
</launch>

那么对应到cpp中,对于这两种param的获取方式有所不同:

#include<ros/ros.h>

int main(int argc, char **argv){
	ros::init(argc, argv, "param_demo");
	ros::NodeHandle nh_global;
	ros::NodeHandle nh_local("~");
	int parameter1, parameter2, parameter3, parameter4;
	
	parameter1 = nh_global.param("param1", 1111);
	parameter3 = nh_global.param("param_demo/param3", 1111);	//获取局部参数,需要增加包名

	parameter2 = nh_local.param("/param2", 2222);	//获取全局参数,需要增加 "/""
	parameter4 = nh_local.param("param4", 2222);
	
	ROS_INFO("parameter param1 = %d", parameter1);
	ROS_INFO("parameter param2 = %d", parameter2);
	ROS_INFO("parameter param3 = %d", parameter3);
	ROS_INFO("parameter param4 = %d", parameter4);

	
	ros::spin();
    return 0;
}

按照这样的配置运行launch文件,输出结果为:

[ INFO] [1599231214.229291485]: parameter param1 = 1
[ INFO] [1599231214.229367939]: parameter param2 = 2
[ INFO] [1599231214.229398017]: parameter param3 = 3
[ INFO] [1599231214.229421101]: parameter param4 = 4

参考链接:
[1] 中科院软件所-机器人操作系统入门(ROS入门教程)- P15-4.2 Parammeter Server: https://www.bilibili.com/video/BV1mJ411R7Ni?p=15
[2] Changkun -github :https://github.com/sychaichangkun/ROS-Academy-for-Beginners

<think>好的,我现在需要回答用户关于如何使用ADB工具监测Android应用性能的问题。首先,我需要回忆一下ADB相关的知识,并结合提供的引用内容来组织答案。 用户提到了引用[1]、[3]和[4],其中引用[1]提到了ADB查看设备列表和CPU使用情况的命令,引用[3]提到了Systrace和内存监测,引用[4]介绍了Pandora工具。因此,我需要将这些信息整合起来,分步骤说明如何用ADB监测性能。 首先,应该介绍ADB的基本连接步骤,确保设备已连接,如adb devices。然后,按照不同的性能指标分点说明,比如CPU、内存、GPU、帧率等。每个部分需要给出具体的命令和解释,例如使用adb shell dumpsys cpuinfo来查看CPU使用情况。 接下来,结合引用[3]中的Systrace,需要说明如何使用这个工具生成性能报告,并分析应用性能。此外,内存监测部分可以参考引用[3]中的Debug.getMemoryInfo(),但用户问的是ADB,所以可能需要用adb shell dumpsys meminfo命令。 还需要提到其他工具如Pandora(引用[4]),但用户主要问的是ADB,所以这部分可能作为补充说明。需要确保每个步骤的命令正确,并且语法正确,比如使用$ adb devices这样的代码块。 另外,用户要求生成相关问题,我需要根据内容提出几个相关问题,比如如何分析内存泄漏、Systrace的使用步骤等。要确保问题相关且有引导性。 最后,检查是否符合格式要求,行内公式用$...$,独立公式用$$...$$,但在这个问题中可能不需要数学公式。确保引用标识正确添加,例如在提到CPU监控时引用[1],提到Systrace时引用[3]。 现在组织内容结构,分步骤说明各个性能指标的监测方法,并补充相关工具和技巧,最后生成相关问题。</think>### 如何使用 ADB 工具监测 Android 应用性能? 以下是基于 ADB 的常用性能监测方法,涵盖 **CPU、内存、GPU、帧率** 等关键指标: --- #### **1. 准备工作:连接设备** - 确保设备已开启 USB 调试,并通过 USB 连接电脑。 - 执行命令查看设备是否连接成功: ```bash $ adb devices ``` 输出中包含设备序列号即表示连接正常[^1]。 --- #### **2. 监测 CPU 使用情况** - **查看实时 CPU 占用**: ```bash $ adb shell top -n 1 | grep <包名> ``` 输出包含进程的 CPU 占用率、线程数等信息。 - **查看历史 CPU 数据**: ```bash $ adb shell dumpsys cpuinfo | grep <包名> ``` 可获取应用的总 CPU 使用率及系统负载[^1]。 --- #### **3. 监测内存使用** - **查看内存详情**: ```bash $ adb shell dumpsys meminfo <包名> ``` 输出包括 Native Heap、Java Heap、PSS 等内存分布,帮助定位内存泄漏或过度消耗[^3]。 - **实时监控内存变化**: ```bash $ adb shell procrank | grep <包名> ``` 动态观察应用内存占用趋势。 --- #### **4. 分析 UI 渲染性能** - **帧率监测(FPS)**: ```bash $ adb shell dumpsys gfxinfo <包名> ``` 输出包含 **Draw、Prepare、Process** 各阶段耗时,若帧耗时超过 16ms(60FPS),则可能发生卡顿[^3]。 - **启用 GPU 渲染模式分析**: ```bash $ adb shell setprop debug.hwui.profile true $ adb shell stop && adb shell start ``` 重启应用后,通过 `adb logcat` 查看 GPU 渲染日志。 --- #### **5. 使用 Systrace 进行系统级分析** - **生成性能报告**: ```bash $ python systrace.py -t 5 -o output.html sched gfx view wm ``` 报告会展示 CPU 调度、UI 线程阻塞、渲染耗时等详细信息,帮助定位性能瓶颈[^3]。 --- #### **6. 补充工具与技巧** - **网络请求监控**: ```bash $ adb shell tcpdump -i any -s 0 -w /sdcard/capture.pcap ``` 抓取网络数据包,分析应用请求延迟。 - **快速调试工具(Pandora)**: 集成在应用内的工具箱(需代码依赖),可直接查看数据库、网络日志等,辅助定位问题[^4]。 --- §§ 1. 如何通过 ADB 分析 Android 应用的内存泄漏? 2. Systrace 报告中如何解读 UI 线程的卡顿原因? 3. 除了 ADB,还有哪些工具可以辅助优化 Android 应用的启动速度? 4. 如何监测 Android 应用的电池消耗情况? --- 以上方法结合 ADB 命令和系统工具,可系统化定位性能问题。实际使用时需根据场景选择合适工具,并配合代码优化(如减少主线程阻塞、内存复用等)提升应用体验。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值