惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

月光博客
月光博客
D
Docker
腾讯CDC
J
Java Code Geeks
大猫的无限游戏
大猫的无限游戏
The Cloudflare Blog
Martin Fowler
Martin Fowler
MongoDB | Blog
MongoDB | Blog
博客园 - Franky
博客园 - 三生石上(FineUI控件)
Recent Announcements
Recent Announcements
F
Fortinet All Blogs
IT之家
IT之家
WordPress大学
WordPress大学
M
MIT News - Artificial intelligence
爱范儿
爱范儿
Microsoft Azure Blog
Microsoft Azure Blog
Vercel News
Vercel News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
小众软件
小众软件
N
Netflix TechBlog - Medium
T
Tailwind CSS Blog
Engineering at Meta
Engineering at Meta
博客园 - 【当耐特】

博客园 - 小狮子

工业搬运机器人(AGV)为什么要选择视觉导航 使用Qt5+CMake实现图片的区域选择(附源码) - 小狮子 - 博客园 儿童节特刊 | 如何练好手眼协调能力(手眼标定详解,附源码) Ceres Solver: 高效的非线性优化库(二)实战篇 - 小狮子 Ceres Solver: 高效的非线性优化库(一) Eigen对齐(加速)方案 计算机立体视觉之-相机针孔模型 微分几何在机器人领域的应用(二)深入理解三维空间变换 微分几何在机器人领域的应用(一) Ubuntu系统无法识别Logitech M590蓝牙鼠标的问题 简单三维空间的旋转矩阵的计算 PCL 库存在vtk的问题导致libproj.so链接错误 Git常用使用技巧 Qt 5.x 开发技巧 ROS (Robot Operating System) 相关资料与文档 图形图像技术在手游中的潜在应用 Construct the intermediate positions, the ribs along two rails Rebuild 3rd Libraries 早期人肉实现 - 简单排序算法代码
机器人平台框架Yarp - Yet another robot platform
小狮子 · 2017-04-12 · via 博客园 - 小狮子

简介

ROS有强大和易用的特性,用的人很多,目前已经推出2.0版本,有相关的官网和论坛。然而其缺点也比较明显。

      只能基于Ubuntu系统,且一个ROS版本只能对应一个具体的Ubuntu版本
      通信效率相对较低,基于Tcp协议。据说2.0以后支持udp协议,但效率如何位置,据说2.0以后版本变化也比较大
      系统较大。ROS使用与一个系统较大的平台,包括移动机器人、机械臂、平台机器人、室外展示机器人等。对于一般的开发者而已,往往只专注与1~2个核心点,很少涉及全部功能。而ROS的升级和维护往往涉及较大的文件和相关库,开发并不轻便。

故需要找到替代品。Yarp标榜了“Another"不知作者是否是相对ROS而言。

Yarp是开源系统,源码在Github中可以得到,且有几个稳定版本共选择。https://github.com/robotology/yarp
官方文档在 http://www.yarp.it/

然而官方文档似乎由doxgen生成,并不条理,且很多文档并没有相关注释,tutorial下来也没有一个明确的理解概念,所以在此需要记录学习过程的体会和经验,希望给后来者提供需求和帮助。

Yarp的优势:

  •        分布式,支持tcp/udp/http 协议
  •        跨平台,用c++编写,依赖库很少,Linux下只需要必备的几个三方库。Windows下需额外下载一个库编译后即可使用
  •        开源,支持修改
  •           简单,支持CMake工具

基于以上有点,在跨平台开发时得心应手,目前没有碰到太多效率问题,比较时候当前的项目需求。

安装

      利用Git工具获取源码或相应稳定版本 https://github.com/robotology/yarp
      Windows下尚需按照源码ACE
      利用CMake生成工程,编译,设定YARP_DIR为CMake相关目录

      Enjoy!

简单实例

  新建CMakeLists.txt, 内容如下

1 cmake_minimum_required(VERSION 2.8.12)
2 
3 project(yarp_demo)
4 
5 find_package(YARP REQUIRED)
6 include_directories(${YARP_INCLUDE_DIRS})
7 add_executable(simple_sender simple_sender.cpp)
8 
9 target_link_libraries(simple_receiver ${YARP_LIBRARIES})

  简单的CMake代码,主要包含Yarp引用的header files,以及在链接时需要加入的Yarp库。Windows和Linux下面均经过测试。其中Windows需要在环境变量中指定Yarp_dir。当然,Yarp最好是自己编译通过。

  simple_sender.cpp的源码如下:

#include <yarp/os/Network.h>
#include <yarp/os/Port.h>
#include <yarp/os/Bottle.h>
#include <yarp/os/Time.h>
#include <stdio.h>
#include <yarp/os/all.h>
#include <yarp/sig/all.h>

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace yarp::os;
using namespace yarp::sig;
using namespace yarp::sig::draw;
using namespace yarp::os;


int main(int argc, char **argv)
{
    char* ipAddr = "127.0.0.1";
    const int defaultPort = 10000;

        Network yarp;
    
        // connect to the name server
        Contact nameServer(ipAddr, defaultPort);
        Network::setNameServerContact(nameServer);
    

    BufferedPort<ImageOf<PixelRgb> > port;
    port.open("/circle");

    cv::VideoCapture mCap;

    mCap = cv::VideoCapture(0);
    if (mCap.isOpened())
    {
        while (1)
        {
            cv::Mat frame;
            mCap >> frame;

            ImageOf<PixelRgb>& img = port.prepare(); 
            img.setExternal(frame.data, frame.cols, frame.rows);
            port.write();


            cv::imshow("image", frame);
            int val = cv::waitKey(30);
            if(val > 0) break;
        }

    }
    else
    {
        int ct = 0;
        int idx = 0;
        while (true)
        {
            ImageOf<PixelRgb>& img = port.prepare();
            img.resize(100, 100);
            img.zero();

            PixelRgb blue(0, 0, 255);
            addCircle(img, blue, ct, 50, 10);

            printf("send msg: %d \n", ++idx);
            port.write();

            Time::delay(1);
            ct = (ct + 6) % 100;
            if (idx > 0xffff) break;
        }

    }
    
    mCap.release();
        port.close();    
    return 0;
}

  相对于Yarp Example里面的范例,本例略复杂,即将发送的数据由OpenCV采集摄像头的数据,再转化为图片格式,发送出去。如果客户端没有摄像头,则直接创建一张简单图片,画一个圆形发送出去。

  其接受代码如下simple_receiver.cpp(CMakeList可参照上面的写,非常简单):

#include <yarp/os/Network.h>
#include <yarp/os/Port.h>
#include <yarp/os/Bottle.h>
#include <stdio.h>

#include <yarp/os/all.h>
#include <yarp/sig/all.h>

using namespace yarp::os;
using namespace yarp::sig;
 
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <string>

int main(int argc, char **argv)
{
    std::string ipAddr("127.0.0.1");
    const int defaultPort = 10000;

    Network yarp;    
    // connect to the name server
    Contact nameServer(ipAddr, defaultPort);
    Network::setNameServerContact(nameServer);

    Port input;
    auto ret = input.open("/receiver");
    if (!ret)
    {
        printf("Could not connect server \n. ## Please retry. \n");
        return -1;
    }
    
    Bottle bot; 
    ImageOf<PixelRgb> img;
    
    Network::connect("/circle", "/receiver", "udp");
 
    while (true)
    {

        input.read(img);
        auto img2 = img.getIplImage();
        IplImage *img3 = static_cast<IplImage*>(img2);
        
        cvShowImage("Image", img3);
        cvWaitKey(20);


        printf("\t======================== \n");
        //printf("got msg: %s\n", bot.toString().c_str());
    }
    
    
    
    input.close();
    
    return 0;
}

  连接正常的话,可以实时收到sender发送过来的图像。

其他几个要点:

  Network::connect函数的第三个参数可选择tpc或upd

  Yarp默认不需要选择ipAddr或者port。在多机通信时,需要指定ip或端口

  单机通信效率比较高。

另外Yarp含有Ros的结构,同时也有类似Ros的Topic的概念,会我后面的文章中介绍。