导航

    蓝鲸ROS机器人论坛

    • 注册
    • 登录
    • 搜索
    • 版块
    • 话题
    • 热门
    1. 主页
    2. weijiz
    3. 帖子
    ROS交流群
    ROS Group
    产品服务
    Product Service
    开源代码库
    Github
    官网
    Official website
    技术交流
    Technological exchanges
    激光雷达
    LIDAR
    ROS教程
    ROS Tourials
    深度学习
    Deep Learning
    机器视觉
    Computer Vision
    • 资料
    • 关注 0
    • 粉丝 11
    • 主题 248
    • 帖子 705
    • 最佳 11
    • 群组 1

    weijiz 发布的帖子

    • ROS C++代码风格说明
      1. 动机
        代码风格是重要的。整洁一致的代码风格能够让代码更加容易阅读,更容易测试和维护。我们努力编写程序不仅让它现在能够正常工作,同时也要保证能够在许多年后被其他开发者继续使用。

      为了这个目的,我们规定了一系列规则。我们的目标是鼓励敏捷且合理的能够让其他开发者容易理解的代码。

      这些是指导准则并不是规则。这篇文章并不完全禁止一些C++的模式或者功能,只是介绍更好的实现方式。当偏离这个准则的时候你要在代码中说明原因。

      最重要的是保持一致性。尽可能的遵守此准则。但是如果你是在更改别人的已经存在的软件包。那就要遵循别人已经存在的代码风格。

      1. ROS代码自动格式规范化

      为什么在我们忙着创造机器人的时候要话大量时间去手动修改代码格式。用机器人来自动格式规范化你的代码吧。这些指令能够自动规范你的代码。

      1. 有很多C++的代码是在这个标准发布之前写的。所有在代码库中有很多代码是不符合这个标准的。下面是在使用这些代码是的建议
      • 所有新开发的软件包都应该符合这个标准
      • 除非你有很多空闲时间,否则不要去尝试把代码修改成符合此规则。
      • 如果你是一个软件包的作者,请花时间把软件包更新为符合这个规则。
      • 如果你在小范围的修改一个软件包,请遵循这个软件包自己的代码风格。不要混合不同风格的代码。
      • 如果你在大范围修改一个软件包,那么请花时间把这个软件包修改为符合此代码风格。
      1. 命名规则
        下面的词用来代指各种命名规则
        • CamelCased: 第一个字母大写,以后每个词的首字母大写
        • camelCased: 第一个字母小写,以后每个词的首字母大写
        • under_scored: 只使用小写字母,不同词之间用下划线隔开
        • ALL_CAPITALS: 只使用大写字母,不同的词间用下划线隔开。

      4.1 软件包
      ROS软件包的命名规则为under_scored
      这个不止适用于C++的代码。查看开发指南了解更多信息

      4.2 话题和服务
      ROS话题和服务的名称命名规则为under_scored
      同样这也不止适用于C++代码。查看开发指南了解更多信息

      4.3 文件
      所有的文件名都是 under_scored
      源文件的扩展名为.cpp
      头文件的扩展名为.h
      要描述清楚,比如不要使用laster.cpp使用hokuyo_topurg_laser.cpp.
      如果一个文件主要是实现一个class.那么就根据这个类去命名文件。比如 ActionServer 的文件为action_server.h

      4.3.1 库文件
      库文件命名规则为under_scored
      不要在lib前缀之后直接添加库名称
      比如

      lib_my_great_thing ## Bad
      libmy_great_thing ## Good
      

      4.4 类和类型
      类的命名规则为CamelCased
      比如

      class ExampleClass;
      

      例外情况,如果这个类名字本身包含缩写那么缩写名称要大写,比如

      class HokuyoURGLaser;
      

      根据这个类是什么来命名这个类。如果你无法描述这个类是什么也许你还没有设计好。如果一个类的名称包含了三个词以上,那么这可能是由于你的设计不够清晰。

      请参考 Google: Type names

      4.5 函数和方法
      通常情况下函数和方法的命名规则是camelCased,其参数的命名规则是under_scored,比如

      int exampleMethod(int example_arg);
      

      函数和方法通常是为了实现否个行为,所以他们的名称要体现出它们要做什么。比如使用checkForErrors()而不要使用errorCheck(),使用dumpDataToFile() 而不要使用dataFile()。类通常都是名词。通过把函数名称设计为动词可以让其他的命名更加自然。

      4.6 变量
      通常情况下变量名是under_scored
      变量命名要尽可能的具有描述性。更长的变量名并不会占用更多的内存。当然整型迭代变量可以非常的短。比如i,j,k.但是变量使用一定要保持一致性。比如i在外部循环,j在内部循环。

      STL迭代变量要能看出来他们是迭代器

      std::list<int> pid_list;
      std::list<int>::iterator pid_it;
      

      或者从变量名能够看出迭代器的类型

      std::list<int> pid_list;
      std::list<int>::iterator int_it;
      

      4.6.1 常量
      常量使用ALL_CAPITALS
      4.6.2 成员变量
      类的成员变量使用 under_scored。同时尾部添加一个下划线

      int example_int_;
      

      4.6.3 全局变量
      尽可能避免使用全局变量。当使用时,全局变量要under_scored 同时在前面加上g_

      // I tried everything else, but I really need this global variable
      int g_shutdown;
      

      4.7 命名空间
      命名空间要under_scored
      5. 协议声明
      所有的源文件和头文件头部都必须包含协议和版权声明。
      在ros-pkg和wg-ros-pkg源LICENSE 文件夹中包含了协议的模板。
      查看ROS开发指南了解更多关于协议和版权的信息。

      1. 格式
        你的编辑器应该能够自动设置格式。
        每一个块级结构要缩进两个空格,不要使用tab
        命名空间的内容并不需要缩进。
        大括号无论是左括号还是右括号都要独占一行。
      if(a < b)
      {
        // do stuff
      }
      else
      {
        // do other stuff
      }
      

      如果只有一行代码,那么括号可以省略

      if(a < b)
        x = 2*a;
      

      当执行的代码比较复杂的时候不要省略大括号

      if(a < b)
      {
        for(int i=0; i<10; i++)
          PrintItem(i);
      }
      

      下面是一个更完整的例子

      /*
       * A block comment looks like this...
       */
      #include <math.h>
      class Point
      {
      public:
        Point(double xc, double yc) :
          x_(xc), y_(yc)
        {
        }
        double distance(const Point& other) const;
        int compareX(const Point& other) const;
        double x_;
        double y_;
      };
      double Point::distance(const Point& other) const
      {
        double dx = x_ - other.x_;
        double dy = y_ - other.y_;
        return sqrt(dx * dx + dy * dy);
      }
      int Point::compareX(const Point& other) const
      {
        if (x_ < other.x_)
        {
          return -1;
        }
        else if (x_ > other.x_)
        {
          return 1;
        }
        else
        {
          return 0;
        }
      }
      namespace foo
      {
      int foo(int bar) const
      {
        switch (bar)
        {
          case 0:
            ++bar;
            break;
          case 1:
            --bar;
          default:
          {
            bar += bar;
            break;
          }
        }
      }
      } // end namespace foo
      

      6.1 行的长度
      一行最多包含120个字符

      6.2 #ifndef 保护
      所有的头文件都必须用#ifndef保护起来

      #ifndef PACKAGE_PATH_FILE_H
      #define PACKAGE_PATH_FILE_H
      ...
      #endif
      

      这部分保护代码要立即添加在协议声明之后。同时#endif添加在文件尾部。

      1. 文档
        代码必须要有文档。没有文档的代码也许能够工作但是没有办法维护。
        我们使用doxygen来自动生成文档。Doxygen 会解析你的代码从代码中提取出对应的文档。

      查看rosdoc页面了解更多的doxygen文档信息。

      所有的方法,函数,类,类成员变量,枚举类型,和常量都需要文档说明。

      1. 终端输出
        避免使用printf 和cout。使用rosconsole来输入信息。其具有下面的优点
      • 有颜色
      • 能够通过显示级别来控制输出
      • 通过/rosout发布,所以网络中的其他用户也能查看
      • 可以选择输出到文件中。
      1. 宏定义

      尽量避免使用宏定义。和常量变量和内联函数不同,宏定义既没有类型也没有作用域。

      1. 预处理指令(#if #ifdef)
        对于条件编译的情况,总是使用#if 不要使用#ifdef
        有些人会这样写代码
      #ifdef DEBUG
              temporary_debugger_break();
      #endif
      

      其他人可能会这样编译

      cc -c lurker.cpp -DDEBUG=0
      

      总是使用#if,。这样能够保证程序正常工作。即使DEBUG没有定义。

      #if DEBUG
              temporary_debugger_break();
      #endif
      
      1. 输出参数
        函数和方法中的输出参数通过传指针进行而不是传引用。
      int exampleMethod(FooThing input, BarThing* output);
      

      通过传引用的方式,调用者无法判断参数是否能被修改。

      1. 命名空间
        鼓励使用命名空间来给代码增加作用域。根据软件包的功能选择一个具有描述性的名称。不要在头文件中使用using-directives . 否则所有使用这个头文件的文件的命名空间都会被污染.使用 using-declarations。这样只有想要使用的名称才会被影响。
        比如不要使用
      using namespace std; // Bad, because it imports all names from std::
      

      使用

      using std::list;  // I want to refer to std::list as list
      using std::vector;  // I want to refer to std::vector as vector
      
      1. 继承
        继承是经常用来定义接口的方式。基础类定义了接口,然后子类实现对应接口。
        继承也通常被用来给子类提供通用的代码。这种继承的使用方法是不建议的。因为子类中包含了基类的实例,所以可以实现同样的目的,同时也有更少的迷惑性。

      当在子类中覆盖一个虚拟方法时,一定要声明称virtual,这样读者才知道发生了什么。

      13.1 多重继承
      尽量避免多重继承,它会产生各种各样的问题。

      1. 异常
        异常是相对于返回整型错误码更好的一种错误报告方式。
        一定要把你的软件包中每个函数和方法可能抛出的异常在文档中说明。
        不要在destructors中抛出异常。
        不要在你不直接调用的回调函数中抛出异常
        如果你在代码中使用错误码而不使用异常,那么就一直使用错误码。一定要保持一致性。

      14.1 编写异常安全的代码
      当你的代码能过够被异常中断时,一定要确认所有的资源都被释放。比如互斥锁要释放,动态内存要释放。

      1. 枚举类型
        把你的枚举类型放在命名空间中
      namespace Choices
      {
        enum Choice
        {
           Choice1,
           Choice2,
           Choice3
        };
      }
      typedef Choices::Choice Choice;
      

      这样方式枚举类型污染命名空间。枚举类型中的元素可以Choices::Choice1这样访问。但是typedef 仍然允许在命名空间外使用去声明Choice枚举类型。

      1. Globals
        全局的无论是变量还是方法都要尽量避免使用。他们会污染命名空间,减少代码的重用性。

      全局变量是最最应该避免的。它阻碍了多实例,同时使得多线程编程成为噩梦。

      大部分的变量和函数应当在类里面声明。剩下的要在命名空间中声明。
      例外情况: 一个文件可能包含main()函数和其他一些小的全局的工具函数。但是注意这些有用的函数可能以后也对其他人很有用。

      1. 静态类变量
        尽量避免使用静态类变量。它同样也会使得无法多次实例化代码,同时也使得多线程编程变成一个噩梦

      2. 调用exit()
        只在设计好的一个退出程序的地方调用exit()
        不要在库文件中调用exit

      3. Assertions
        使用assertions 来检查条件,数据结构,和内存管理器的返回值。使用Assertions 要比使用条件声明更好。
        不要直接使用assert()。使用在ros/assert.h里面声明的函数

      /** ROS_ASSERT asserts that the provided expression evaluates to
       * true.  If it is false, program execution will abort, with an informative
       * statement about which assertion failed, in what file.  Use ROS_ASSERT
       * instead of assert() itself.
       * Example usage:
       */
         ROS_ASSERT(x > y);
      
      /** ROS_ASSERT_MSG(cond, "format string", ...) asserts that the provided
       * condition evaluates to true.
       * If it is false, program execution will abort, with an informative
       * statement about which assertion failed, in what file, and it will print out
       * a printf-style message you define.  Example usage:
       */
         ROS_ASSERT_MSG(x > 0, "Uh oh, x went negative.  Value = %d", x);
      
      /** ROS_ASSERT_CMD(cond, function())
       * Runs a function if the condition is false. Usage example:
       */
         ROS_ASSERT_CMD(x > 0, handleError(...));
      
      /** ROS_BREAK aborts program execution, with an informative
       * statement about which assertion failed, in what file. Use ROS_BREAK
       * instead of calling assert(0) or ROS_ASSERT(0). You can step over the assert
       * in a debugger.
       * Example usage:
       */
         ROS_BREADK();
      

      不要在assertion里面运行程序。只用它来检查逻辑条件。根据编译的设置assertion可能不会被执行。

      在软件开发的时候开启assertion检查时很必要的。当软件接近完成,在深入的测试代码中assertion一直成立。那么你可以添加一个编译flag,把assertion代码从编译中移除。这样这部分代码就不会在占用空间和CPU资源。下面的catkin_make选项会为你的所有的软件包定义NDEBUG宏,从而移除assertion检查。

      catkin_make -DCMAKE_CXX_FLAGS:STRING="-DNDEBUG"
      

      注意: 当你执行这个命令后cmake会编译你的所有软件。同时会把设置记录下来。除非你删除build和devel文件夹。

      发布在 技术交流
      weijiz
      weijiz
    • RE: 教程20里面出现的问题

      @rockyren 这个是程序崩溃了,你可以单独执行 错误里面cmd后面的指令,看看输出是什么。

      0_1527219254134_18b86f01-75de-4daf-8164-4778121a1ace-image.png

      发布在 技术交流
      weijiz
      weijiz
    • ROS Python 代码风格说明

      此文翻译自ROS wiki

      本文定义了一个在开发ROS Python程序时应当遵循的代码风格指南。这个适用于所有的ROS代码,无论是核心还是非核心代码。

      1. 代码风格
        Python的代码应当遵循PEP8标准。PEP8并不是一个严格的代码风格标准。它对于代码可读性的要求要高于标准的一致性。所以在写代码的时候要灵活对待这个标准。下面是PEP8的一个简单总结
      • package_name
      • ClassName
      • method_name
      • field_name
      • _private_something
      • self.__really_private_field
      • _global
      • 4 space indentation
      1. load
        这里只是对于使用 rosbuild/rosmake的软件包有效。如果你使用c的是catkin则不能使用roslib,load_manifest
        (鉴于现在大家基本都在使用catkin,这一段略过)

      2. 软件包和模块的命名规则(__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的导出路径。

      1. 节点文件

      在ROS中,节点的类型和节点文件的名称一样。一般情况下,这意味着在你的文件代码的头部添加#!/usr/bin/env python, 同时文件名为节点的名字。

      如果你的节点很简单,一个文件可能就包含了所有的代码。否则很有可能要在代码中引入其他代码。

      注意: 我们努力把和ROS相关的代码与能够重用的和通用的代码分开。 把节点文件和放置在src/packagename文件夹内文件分开能够很好的实现这个目的。

      1. 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中被限制使用
      发布在 技术交流
      weijiz
      weijiz
    • RE: 教程20里面出现的问题

      @rockyren scipy没有安装

      sudo pip install scipy
      
      发布在 技术交流
      weijiz
      weijiz
    • RE: 教程20里面出现的问题

      @rockyren
      0_1527037167931_874b537c-7542-4c46-b4b6-a36cbaed5645-image.png
      你在编译的时候有这个错误。因为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"
      
      发布在 技术交流
      weijiz
      weijiz
    • RE: 机器人的话题

      @zhongguorenmin 不太明白你的问题,看话题数据直接 rostopic echo [topic 名称] 就可以了

      发布在 技术交流
      weijiz
      weijiz
    • hikey 970 开发板刷基础固件和Android系统

      刷板子的系统主要包括两个方面,一个是基础固件,一个就是系统文件。根据板子上面四个开关状态的不同板子会处在不同的状态。

      0_1526694882717_Screenshot from 2018-05-19 09-54-20.png

      开关位于图中的22的位置
      这四个开关的功能分别是

      1. 自动开机
        这个开关如果是On,当板子通电的时候就会自动启动系统。反之则上电之后要按电源键启动。
      2. 启动模式
        开关是On的时候上电后启动至刷基础固件模式,这时候可以通过程序给板子刷基础固件。当是off的时候系统会从已经安装的bootloader启动。
      3. 系统启动模式
        当是On的时候系统会以UEFI模式启动,反之则会直接启动系统
      4. 扩展功能选择
        当是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可能的原因是

      1. 你安装过modemmanager,这个程序会给我们的板子发数据导致程序写入失败。解决方法很简单,卸载这个软件
      sudo apt-get purge modemmanager
      
      1. 你刷入了错误的固件。可能你的固件是从别的地方下载的,也可能是自己编译的。如果是这样那么很有可能是固件自身出了问题。

      系统镜像

      实际上在刷入上个基础固件的时候会自动的把系统镜像也刷入进去。这时候把板子上的开关设置为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
      
      发布在 技术交流
      weijiz
      weijiz
    • 海思 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

      0_1526694480039_b9441cfc-3dac-4973-87c9-077fc78e70ef-image.png

      0_1526694393637_7673a326-e78a-4335-9f33-26fdaae78915-image.png

      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的官网上。

      文档主页

      Github 文档主页

      hikey970 相关软件 这里放的是hikey系列板子的相关软件。有些是某些板子独有的,从名称上能看出来比如 tools-images-hikey970。还有一些是通用的,但是针对不同的板子有不同的分支。比如 l-loader。

      注意目前的文档很不完善,里面有些东西是有问题的。有些软件也不能完全按照文档说明使用。虽然官方说明支持AOSP,Ubuntu,Debian。但是目前(2018.5.19)还是只支持AOSP。

      发布在 技术交流
      weijiz
      weijiz
    • RE: 原装和国产ps3手柄ros驱动程序

      @jianjun 可能是树莓派的问题,树莓派的蓝牙驱动好像有问题。你可以换电脑试试。

      发布在 产品服务
      weijiz
      weijiz
    • RE: 求教catkin_make编译问题

      @网上如烟 你的命令写错了是 -DCATKIN_WHITELIST_PACKAGES=, 这个是可以用tab自动补全的,更不容易出错。

      发布在 技术交流
      weijiz
      weijiz
    • RE: 添加传感器

      @zhongguorenmin 运行下面的指令

      git clone http://git.bwbot.org/publish/xiaoqiang-cmds
      cd xiaoqiang-cmds
      git checkout kinetic
      sudo ./fixudev
      

      这个指令会自动添加udev规则。注意第一步clone可能会失败,如果失败就多试几次。

      发布在 讨论区
      weijiz
      weijiz
    • RE: 原装和国产ps3手柄ros驱动程序

      @jianjun 你可能用的不是小强系统。直接运行roscore,而且要一直运行,不能关闭。

      发布在 产品服务
      weijiz
      weijiz
    • 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()
      
      发布在 技术交流
      weijiz
      weijiz
    • RE: 原装和国产ps3手柄ros驱动程序

      @jianjun 这是由于roscore没有启动,可能你把startup服务关闭里。运行

      sudo service startup start
      

      可以启动服务。

      发布在 产品服务
      weijiz
      weijiz
    • RE: 原装和国产ps3手柄ros驱动程序

      @wukefu 你在操作这一步之前有没有通过USB数据线绑定?

      发布在 产品服务
      weijiz
      weijiz
    • RE: 颜色识别

      @laijin 如果没有数据发布就不是坐标系的问题,有可能是你订阅的topic不对,默认订阅的topic名称和你实际的topic名字是不一样的,要做一下remap

      发布在 技术交流
      weijiz
      weijiz
    • RE: 改变上位机问题。

      @zhongguorenmin 把要移植的软件的相关依赖全部安装完成,然后把树莓派的工作空间内的代码添加到自己笔记本内的工作空间,然后再编译。

      发布在 技术交流
      weijiz
      weijiz
    • RE: 颜色识别

      @laijin 有可能是坐标系不对,也有可能是点云数据没发出来。可以看看rviz里面是不是有错误提示。

      发布在 技术交流
      weijiz
      weijiz
    • RE: 颜色识别

      @laijin 这是一个nodelet, 启动方式和一般的node不一样

      # 启动nodelet manager
      rosrun nodelet nodelet manager
      # 启动处理的nodelet
      rosrun nodelet nodelet load depth_image_proc/point_cloud_xyz manager
      

      最好写一个launch文件去处理,把你的topic remap到wiki里对应的topic

      发布在 技术交流
      weijiz
      weijiz
    • RE: rviz

      @laijin 和kinect相关的,点击会有下拉菜单,从里面选择。具体是那个我也不清楚。

      发布在 技术交流
      weijiz
      weijiz
    • 1
    • 2
    • 26
    • 27
    • 28
    • 29
    • 30
    • 35
    • 36
    • 28 / 36