@rockyren 这个是程序崩溃了,你可以单独执行 错误里面cmd后面的指令,看看输出是什么。
ROS Group 产品服务
Product Service 开源代码库
Github 官网
Official website 技术交流
Technological exchanges 激光雷达
LIDAR ROS教程
ROS Tourials 深度学习
Deep Learning 机器视觉
Computer Vision

weijiz 发布的帖子
-
ROS Python 代码风格说明
此文翻译自ROS wiki
本文定义了一个在开发ROS Python程序时应当遵循的代码风格指南。这个适用于所有的ROS代码,无论是核心还是非核心代码。
- 代码风格
Python的代码应当遵循PEP8标准。PEP8并不是一个严格的代码风格标准。它对于代码可读性的要求要高于标准的一致性。所以在写代码的时候要灵活对待这个标准。下面是PEP8的一个简单总结
- package_name
- ClassName
- method_name
- field_name
- _private_something
- self.__really_private_field
- _global
- 4 space indentation
-
load
这里只是对于使用 rosbuild/rosmake的软件包有效。如果你使用c的是catkin则不能使用roslib,load_manifest
(鉴于现在大家基本都在使用catkin,这一段略过) -
软件包和模块的命名规则(
__init__.py
文件)
所有的Python代码必须被放置在一个模块命名空间(module namespace). ROS会把你的Python代码文件夹导出到你的依赖路径里面。所以一定要小心不能和其他人引用的软件包相冲突。我们非常建议你的软件包名称和你的ROS包名称一致。
下面是两种推荐的代码文件布局风格
没有消息或服务的小模块
packagename |- src/ |- packagename.py |- scripts/ |- non-exported python files
有消息和服务的模块
packagename |- src/ |- packagename/ |- __init__.py |- yourfiles.py |- scripts/ |- non-exported python files
如果你不了解什么是
__init__.py
, 我们推荐你看看这篇文章由于 Python的 消息和服务生成程序需要在你的软件包里面生成文件,所以这个更复杂的文件布局是需要的。
在一些罕见的情况下,你不能把你的代码放入
/src
文件夹内(比如 第三方代码),你需要通过修改你的Mainfest文件来覆盖Python的导出路径。- 节点文件
在ROS中,节点的类型和节点文件的名称一样。一般情况下,这意味着在你的文件代码的头部添加
#!/usr/bin/env python
, 同时文件名为节点的名字。如果你的节点很简单,一个文件可能就包含了所有的代码。否则很有可能要在代码中引入其他代码。
注意: 我们努力把和ROS相关的代码与能够重用的和通用的代码分开。 把节点文件和放置在src/packagename文件夹内文件分开能够很好的实现这个目的。
- Python的功能和版本
我们的目标环境是Python 2.5, 尽管我们希望代码能够在Python 2.6,Python2.7 以及Python3K等等环境使用。这意味着:
- 使用新式风格的class
- 不要使用reduce() sum(),在大多数情况下for的效率更高
- 避免使用map() filter(),使用list作为替代
- 不要用反引号代替repr
- 不要用<>代替 “!=”
- 如果你需要真的除法运算(默认是整除) 使用 from future import division
- 使用subprocess , 不要使用popen2, os.popen
- 不要使用 dict.has_key() 用 key in dict
- 不要使用 zip(),range(), map(),filter()因为在以后的版本中会返回迭代器
- 不要使用string.{atoi|atof|…}(),使用int(), float()
- 不要使用 print >> f, “Message”. 使用f.write(“Message\n”)
以各条的的原因
- 不能兼容Python 2.5
- 在Python 3000中被限制使用
- 代码风格
-
RE: 教程20里面出现的问题
@rockyren
你在编译的时候有这个错误。因为ORB_SLAM中opencv的预编译版本的和你自己编译的版本不一样。你要重新编译DBOW2# 编译 DBOW2 cd Thirdparty/DBoW2 mkdir build cd build cmake .. -DCMAKE_BUILD_TYPE=Release make # 编译 ORB_SLAM cd ../../ mkdir build cd build cmake .. -DROS_BUILD_TYPE=Release make # 编译catkin包 cd ~/Documents/ros catkin_make -DCATKIN_WHITELIST_PACKAGES="ORB_SLAM"
-
hikey 970 开发板刷基础固件和Android系统
刷板子的系统主要包括两个方面,一个是基础固件,一个就是系统文件。根据板子上面四个开关状态的不同板子会处在不同的状态。
开关位于图中的22的位置
这四个开关的功能分别是- 自动开机
这个开关如果是On,当板子通电的时候就会自动启动系统。反之则上电之后要按电源键启动。 - 启动模式
开关是On的时候上电后启动至刷基础固件模式,这时候可以通过程序给板子刷基础固件。当是off的时候系统会从已经安装的bootloader启动。 - 系统启动模式
当是On的时候系统会以UEFI模式启动,反之则会直接启动系统 - 扩展功能选择
当是On的时候会使用低速扩展口功能,当是Off的时候会使用蓝牙功能。
基础固件包含了板子的bootloader等等。如果基础固件刷错了系统就不能再启动了。甚至连fastboot也不能使用,也无法再刷其他系统。正常情况下只是刷系统是不需要刷基础固件的。
安装基础程序
sudo apt-get install android-tools-adb sudo apt-get install android-tools-fastboot
基础固件
以下的操作都是在Linux系统环境下完成的
下载镜像
从96boards的970下载主页下载最新的系统镜像。目前(2018.5.19)只有Android的。这个文件中包含了基础固件和系统镜像。
下载完成后你需要解压这个文件。在image文件夹中包含了需要的文件。
下载镜像工具
git clone https://github.com/96boards-hikey/tools-images-hikey970
官方的工具有错误,我们需要进行修改后才能用
在 recovery-flash.sh 的第一行#/bin/bash
改为
#!/bin/bash
将第九行
UEFI_BUILD_PATH=/home/qubo/tools-images-hikey970
改为
UEFI_BUILD_PATH=${PWD}
然后把刚才下载的文件中的
image
里的所有文件复制到tools-images-hikey970
文件夹设置开发板启动方式
把板子的开关设置成 On On On Off,然后上电。按照之前的说明,这时候板子处在刷基础固件的状态。
用数据线通过USB把板子和电脑连接起来。正常情况下你会在/dev/ 文件夹下面发现一个ttyUSBX的设备,X是一个数字可能是0,1之类的。确认自己的板子是对应哪个设备。
刷入固件
运行
sudo ./recovery-flash.sh ttyUSBX # 如果你的设备是ttyUSB0那么你可以省略第二个参数
程序卡在了
wait for devices
可能的原因是- 你安装过modemmanager,这个程序会给我们的板子发数据导致程序写入失败。解决方法很简单,卸载这个软件
sudo apt-get purge modemmanager
- 你刷入了错误的固件。可能你的固件是从别的地方下载的,也可能是自己编译的。如果是这样那么很有可能是固件自身出了问题。
系统镜像
实际上在刷入上个基础固件的时候会自动的把系统镜像也刷入进去。这时候把板子上的开关设置为On Off On Off就可以启动系统了。第一次启动的时候要多等一会,因为Android要先初始化一下。
如果只是要刷系统固件可以只刷入系统固件中的下面几个文件。执行
sudo fastboot flash boot boot.img sudo fastboot flash cache cache.img sudo fastboot flash system system.img sudo fastboot flash userdata userdata.img
- 自动开机
-
海思 hikey970 开发板简介
基本信息
2018年3月19日的Linaro Connect大会上华为正式发布了HiHope Hikey 970开源硬件。HiHope Hikey 970基于华为海思麒麟970,采用了台积电10nm工艺,拥有4核Cortex-A73@2.36GHz和4核Cortex-A53@1.8GHz,12核的Mali-G72。麒麟970是全球首款内置独立NPU(神经网络单元)的移动AI计算平台。HiHope Hikey 970拥有6GB的LPDDR4 和 64GB UFS。外围部分拥有支持4K高清的HDMI 2.0a接口,2个USB3.0接口,2个USB Type-C接口,1个千兆网口,支持CAN V2.0B协议,可以运行AOSP、Ubuntu、Debian等系统。
目前淘宝已经可以买到。
HiHope Hikey 970以强悍的性能和兼容于96Boards CE的标准,在计算机视觉、高性能计算开发、Android标准化程序开发测试等领域有广泛的应用,HiHope Hikey 970不只是开源硬件中的性能怪兽,因为集成了NPU(NPU相比与CPU在能效上有50倍以上的提升,性能上有25倍以上的提升),并且得到了华为HiAI生态的全力支持,在AI等人工智能领域开发中拥有巨大的发展前景,HiHope Hikey 970可运用于深度学习算法、智能机器人、无人驾驶和智慧城市等多个领域。
硬件配置简介
项目 参数 主板: 海思 麒麟 970 - HiAI 架构, NPU CPU: ARM Cortex-A73 MPCore4 @up to2.36GHz, ARM Cortex-A53 MPCore4 @up to1.8GHz GPU: ARM Mali-G72 MP12 GPU 内存: 6GB LPDDR4X 1866MHz 存储: 64GB UFS 2.1, Micro SD 网络: Bluetooth/WIFI/GPS 视频: 1080p@60Hz HDMI, 4 line MIPI/LCD port 摄像头: 4 line MIPI port, 2 line MIPI port 扩展接口: 一个40pin的低速扩展口
UART, SPI, I2S, I2C x2, GPIO x12, DC power
一个60pin 的高速扩展口(HS)
4L-MIPI DSI, USB, I2C x2, 2L+4L-MIPI CSI用户接口: 电源、复位按钮
8个LED指示灯
4 个用户可以自己控制
3 用来显示连接状态 (蓝牙 wifi和 GPS)
1个用来显示can总线电源: 直流: +8V to +18V 系统支持: Android
Linux尺寸: 105.26mm X 100mm 满足 96Boards 客户版本标准尺寸要求. 环境: 运行温度: 0°C to +70°C 96boards 简介
HiKey系列开发板是开源组织Linaro 96Boards的核心成员。Linaro是一个非盈利的开源代码组织,由ARM、飞思卡尔、IBM、Samsung、ST-Ericsson 及德州仪器(TI)等半导体厂商联合,在2010年3月成立。
“市场上这么多公司其实都需要开源软件作为接下来后续推广的平台,客户通过Linaro这个互相协作的平台可能只需要花一成的力气或投入就能实现过去十成投入的效果。”ARM合作伙伴支持部门总经理Monica Biddulph表示,这正是Linaro平台的意义所在。
Linaro成立后,华为、阿里巴巴、中兴通讯、LeMaker、AMD、AppliedMicro、Calxeda、Canonical、Cavium、Facebook、HP、Marvell、红帽等行业内重要公司纷纷加入,可见这个组织在行业内备受认可。而华为海思是Linaro的核心成员,首批“96 boards”开发板便由华为海思提供,这意味着海思在Linaro的开源软件开发方面拥有更大的话语权,可以在芯片开发的过程中及早取得主流开源软件的支持。
而96Boards是ARM开放平台规范,是第一个定义Cortex-A开发板的开放规范,该规范由Linaro社区委员会组织维护,取名96Boards意在说明囊括了“32位+64位”的板卡。基于96Boards规范,可以通过使用标准化平台,缩短开发周期,降低开发成本,加快产品的创新和量产速度。使用96Boards的用户众多,包括各种SoC设计、做外围芯片开发、软件应用设计等方面的客户。
96Boards目前制定了消费版、企业版和物联网版本,目前市面上消费版更为常见。华为此前就推出了支持该规范、基于麒麟620处理器的开发板“HiKey 620”,值得一提的是,HiKey 620还是全球首款符合Linaro 96Boards CE标准的开源硬件产品。
目前(2018.5.19)这块板应该是96boards上的机皇。
文档信息
这款虽然是华为的产品但是主要的文档都在96boards的官网上。
hikey970 相关软件 这里放的是hikey系列板子的相关软件。有些是某些板子独有的,从名称上能看出来比如 tools-images-hikey970。还有一些是通用的,但是针对不同的板子有不同的分支。比如 l-loader。
注意目前的文档很不完善,里面有些东西是有问题的。有些软件也不能完全按照文档说明使用。虽然官方说明支持AOSP,Ubuntu,Debian。但是目前(2018.5.19)还是只支持AOSP。
-
RE: 添加传感器
@zhongguorenmin 运行下面的指令
git clone http://git.bwbot.org/publish/xiaoqiang-cmds cd xiaoqiang-cmds git checkout kinetic sudo ./fixudev
这个指令会自动添加udev规则。注意第一步clone可能会失败,如果失败就多试几次。
-
ROS tf 变换中的时间戳问题
我们从ros wiki 上tf变换的第一个例子说起
#!/usr/bin/env python import roslib roslib.load_manifest('learning_tf') import rospy import tf import turtlesim.msg def handle_turtle_pose(msg, turtlename): br = tf.TransformBroadcaster() br.sendTransform((msg.x, msg.y, 0), tf.transformations.quaternion_from_euler(0, 0, msg.theta), rospy.Time.now(), turtlename, "world") if __name__ == '__main__': rospy.init_node('turtle_tf_broadcaster') turtlename = rospy.get_param('~turtle') rospy.Subscriber('/%s/pose' % turtlename, turtlesim.msg.Pose, handle_turtle_pose, turtlename) rospy.spin()
上面的代码是根据小海龟的位置发布一个从小海龟到 world 的 tf 变换。理想情况下这样是没有问题的,但是实际使用中,这样写就会产生问题。问题的根源就在这个tf的时间戳上
br.sendTransform((msg.x, msg.y, 0), tf.transformations.quaternion_from_euler(0, 0, msg.theta), rospy.Time.now(), turtlename, "world")
这里的程序tf时间戳用的是当前时间,也就是处理这个位置信息时的时间。但是如果我们的机器人性能比较弱,可能处理这个位置信息的时间和位置信息实际产生的时间差挺多。这样当其他数据需要坐标系转换的时候,就会采用错误的tf数据从而产生误差。我们以具体的数字为例
比如我们现在在1s的时刻得到小海龟的位置是(0,0), 小海龟在以1m/s的速度沿X轴直线运动。我们的小海龟性能很弱。消息处理的时间和实际位置消息产生的时间差了1s。我们现在通过超声波测量到了小海龟前面1m处有一个障碍物。我们想知道这个障碍物在world坐标系下的坐标。我们首先找到当前时刻附近的tf变换,但是这个tf变换实际上是根据1s之前小海龟的位置计算的,当时小海龟的位置是(-1,0)。所以根据这个tf变换我们计算出这个障碍物的位置坐标是(0,0)。如果用这个数据去做路径规划,肯定出现的是错误的结果。当然上面是一个夸张的例子,但是实际确实会因此引入误差。那么正确的做法是什么呢?
以消息产生的时间戳作为tf变换的时间戳。因为坐标变换是根据消息计算出来的,所以其有效的时刻就应该是消息有效的时刻。所以上面的例子应该写为#!/usr/bin/env python import roslib roslib.load_manifest('learning_tf') import rospy import tf import turtlesim.msg def handle_turtle_pose(msg, turtlename): br = tf.TransformBroadcaster() br.sendTransform((msg.x, msg.y, 0), tf.transformations.quaternion_from_euler(0, 0, msg.theta), msg.header.timestamp, # 由于这里订阅的是Pose并不是PoseStamped所以没有时间戳。这里只作为示例 turtlename, "world") if __name__ == '__main__': rospy.init_node('turtle_tf_broadcaster') turtlename = rospy.get_param('~turtle') rospy.Subscriber('/%s/pose' % turtlename, turtlesim.msg.Pose, handle_turtle_pose, turtlename) rospy.spin()