<ROS> pluginlib理解与示例

TGK-planner编译报错PLUGINLIB_EXPORT_CLASS解决 TGK-planner编译报错解决。 阅读详情

1. 写在最前面

由于在一个源码中, 关于在ROS平台上的具体实现, 用到了Plugin. 为了更加深入的理解到底是一个什么鬼, 所以对pluginlib进行了一些学习, 下面的内容, 大部分在网站上是能够找到的, 是综合Wiki上的介绍, 以及从源码中看到的内容和自己的尝试. 希望对大家都一点点帮助.

pluginlib是一个使用C++实现的库, 用于在ROS包里面动态的加载或卸载plugin. plugin满足一些条件的, 可以从运行库(例如共享对象, 动态链接库)中动态加载的类. Plugin在扩展或修改应用的行为上很有优势, 并不需要知道原始类的源码, 也许你在编写代码时, 也并不知道你将会用到哪个plugin, 而是在运行时通过参数载入才确定具体的plugin, 在后面有一点相关的示例, 可以体会一下使用plugin的feeling(感觉很一般, 哈哈哈…).

2. 示例

想象一个场景, 假设现在有一个ROS包polygon_interface_package, 里面包含一个polygon基类, 同时, 另外还有两个不同的polygon, 一个是rectangle, 存在于rectangle_plugin包, 另外一个是triangle, 存在于triangle_plugin包. 我们希望rectangle和triangle都被系统支持.

2.1 registering/Exporting a Plugin

为了能够动态加载一个类, 那么, 这个类必须是一个被标注的, 并且导入到系统的一个类. 这个过程, 需要使用宏PLUGINLIB_EXPORT_CLASS来完成. 一般情况下, 这个宏放在实现文件(.cpp)的末尾. 类似如下:

    #include <pluginlib/class_list_macros.h>
    #include <polygon_interface_package/polygon.h>
    #include <rectangle_package/rectangle.h>

    // 具体参数意义, 见下文
    PLUGINLIB_EXPORT_CLASS(rectangle_namespace::Rectangle, polygon_namespace::Polygon)

2.2 The Plugin Description File

每个Plugin都需要由一个插件描述文件, 是一个XML格式机器可读的文件. 包含一些必要的信息, 例如路径, 插件类型, 插件名称等. 类似如下:

    <library path="lib/librectangle">
      <class type="rectangle_namespace::Rectangle" base_class_type="polygon_namespace::Polygon">
      <description>
      This is a rectangle plugin
      </description>
      </class>
    </library>

更多详细的介绍, 可以查看: http://wiki.ros.org/pluginlib/PluginDescriptionFile

2.3 向ROS Package System中注册插件

为了使pluginlib能够查询到所有可用的插件, 需要在package.xml文件中添加export的tag块. 类似如下:

    <export>
      <polygon_interface_package plugin="${prefix}/rectangle_plugin.xml" />
    </export>

一个值得注意的地方, 为了使上述export命令正确执行, 还需要在build和run依赖项中添加如下信息:

    <build_depend>polygon_interface_package</build_depend>
    <run_depend>polygon_interface_package</run_depend>

2.4 Querying ROS Package System For Available Plugins

可以使用rospack命令来查询, 就很简单的一条命令, 类似如下:

    $ rospack plugins --attrib=plugin nav_core

将会返回所有nav_core包中导入的插件.

2.5 Step by Step

2.5.1 创建Plugin

首先, 当然是在自己的工作空间中创建一个用于尝试的ROS Package. 依次输入下述命令.

    $ roscd
    $ cd ../src
    $ catkin_create_pkg plugin_test roscpp pluginlib

OK, 现在可以开始写代码了. 在include/plugin_test文件夹下新建文件polygon_base.h, 将下述代码拷贝进去, 申明我们的基类.

    #ifndef PLUGINLIB_TUTORIALS__POLYGON_BASE_H_
    #define PLUGINLIB_TUTORIALS__POLYGON_BASE_H_

    namespace polygon_base
    {
      class RegularPolygon
      {
        public:
          virtual void initialize(double side_length) = 0;
          virtual double area() = 0;
          virtual ~RegularPolygon(){}

        protected:
          RegularPolygon(){}
      };
    };
    #endif

在include/plugin_test文件夹下新建文件polygon_plugins.h, 将下述代码拷贝进去, 申明我们的插件:

    #ifndef PLUGINLIB_TUTORIALS__POLYGON_PLUGINS_H_
    #define PLUGINLIB_TUTORIALS__POLYGON_PLUGINS_H_
    #include <plugin_test/polygon_base.h>
    #include <cmath>

    namespace polygon_plugins
    {
      class Triangle : public polygon_base::RegularPolygon
      {
        public:
          Triangle(){}

          void initialize(double side_length)
          {
            side_length_ = side_length;
          }

          double area()
          {
            return 0.5 * side_length_ * getHeight();
          }

          double getHeight()
          {
            return sqrt((side_length_ * side_length_) - ((side_length_ / 2) * (side_length_ / 2)));
          }

        private:
          double side_length_;
      };

      class Square : public polygon_base::RegularPolygon
      {
        public:
          Square(){}

          void initialize(double side_length)
          {
            side_length_ = side_length;
          }

          double area()
          {
            return side_length_ * side_length_;
          }

        private:
          double side_length_;

      };
    };
    #endif

在src文件夹下创建文件polygon_plugins.cpp, 并拷贝下述代码进去, 注册我们的插件.

    #include <pluginlib/class_list_macros.h>
    #include <plugin_test/polygon_base.h>
    #include <plugin_test/polygon_plugins.h>

    PLUGINLIB_EXPORT_CLASS(polygon_plugins::Triangle, polygon_base::RegularPolygon)
    PLUGINLIB_EXPORT_CLASS(polygon_plugins::Square, polygon_base::RegularPolygon)

在CMakeLists.txt文件中, 加入下述add_library申明. 值得注意的是, 在CMakeLists.txt文件中, 需要在include_directories中添加include目录, 否则我们前面写的两个头文件将会找不到.

    include_directories(
      ${catkin_INCLUDE_DIRS}
      include
    )

    ... ...

    add_library(polygon_plugins src/polygon_plugins.cpp)

如前所述, 咱还需要编辑关于插件的信息内容, 在plugin_test主目录下, 创建一个polygon_plugins.xml文件, 复制下述内容进入:

    <library path="lib/libpolygon_plugins">
      <class type="polygon_plugins::Triangle" base_class_type="polygon_base::RegularPolygon">
        <description>This is a triangle plugin.</description>
      </class>
      <class type="polygon_plugins::Square" base_class_type="polygon_base::RegularPolygon">
        <description>This is a square plugin.</description>
      </class>
    </library>

在同目录下的package.xml文件中export tag块中添加下述内容:

      <plugin_test plugin="${prefix}/polygon_plugins.xml" />

在命令行中运行下述指令, 对应的输出信息如下所示:

    $ rospack plugins --attrib=plugin plugin_test
    plugin_test /home/silence/WorkSpace/catkin_ws/src/plugin_test/polygon_plugins.xml

如果得到类似的输出, 则表示所有都是没问题的.

2.5.2 使用Plugin

2.5.2.1 基本使用体验

在src目录下, 新建polygon_loader.cpp文件, 用于测试, 复制下述内容:

    #include <pluginlib/class_loader.h>
    #include <plugin_test/polygon_base.h>

    int main(int argc, char** argv)
    {
      pluginlib::ClassLoader<polygon_base::RegularPolygon> poly_loader("plugin_test", "polygon_base::RegularPolygon");

      try
      {
        boost::shared_ptr<polygon_base::RegularPolygon> triangle = poly_loader.createInstance("polygon_plugins::Triangle");
        triangle->initialize(10.0);

        boost::shared_ptr<polygon_base::RegularPolygon> square = poly_loader.createInstance("polygon_plugins::Square");
        square->initialize(10.0);

        ROS_INFO("Triangle area: %.2f", triangle->area());
        ROS_INFO("Square area: %.2f", square->area());
      }
      catch(pluginlib::PluginlibException& ex)
      {
        ROS_ERROR("The plugin failed to load for some reason. Error: %s", ex.what());
      }

      return 0;
    }

并在CMakeLists.txt中加入下述申明, 然后$ catkin_make.

    add_executable(polygon_loader src/polygon_loader.cpp)
    target_link_libraries(polygon_loader ${catkin_LIBRARIES})

编译成功后, 运行节点, 应该会得到下述类似的输出.

    $ rosrun plugin_test polygon_loader
    [ INFO] [1477584281.637794959]: Triangle area: 43.30
    [ INFO] [1477584281.637923253]: Square area: 100.00

上述代码都比较简单, 就不做过多说明了.

2.5.2.2 另一种体验

在src目录下, 新建polygon_loader_v1.cpp文件, 用于测试, 复制下述内容:

    #include <pluginlib/class_loader.h>
    #include <plugin_test/polygon_base.h>

    #include <ros/ros.h>
    #include <sstream>
    #include <string>
    #include <vector>

    template <typename T>
    std::string to_string(T value) {
        std::ostringstream os ;
        os << value ;
        return os.str() ;
    }

    int main(int argc, char** argv)
    {
      ros::init(argc, argv, "polygon_loader_v1");
      ros::NodeHandle n_;

      std::vector<std::string> class_names;
      int class_index = 1;
      while (true)
      {
        std::string class_name;
        std::string param_name = std::string("polygon_loader_v1/derive_class_" + to_string(class_index++));
        if(!n_.getParam(param_name.c_str(), class_name))
            break;
        class_names.push_back(class_name);
      }

      if (class_names.empty()) {
        ROS_ERROR("ros parameter error");
        return 0;
      }

      pluginlib::ClassLoader<polygon_base::RegularPolygon> poly_loader("plugin_test", "polygon_base::RegularPolygon");

      try
      {

        for (class_index = 0; class_index < class_names.size(); ++class_index) {
          std::string class_name = class_names[class_index];
          boost::shared_ptr<polygon_base::RegularPolygon> plugin = poly_loader.createInstance(class_name);
          plugin->initialize(10.0);
          ROS_INFO("The polygon (%d / %d) area: %.2f", class_index + 1, class_names.size(), plugin->area());
        }
      }
      catch(pluginlib::PluginlibException& ex)
      {
        ROS_ERROR("The plugin failed to load for some reason. Error: %s", ex.what());
      }

      ROS_INFO("Waiting \"Ctrl + C\"");
      while (ros::ok()) {
        ;
      }

      return 0;
    }

并在CMakeLists.txt中加入下述申明, 然后$ catkin_make.

    add_executable(polygon_loader_v1 src/polygon_loader_v1.cpp)
    target_link_libraries(polygon_loader_v1 ${catkin_LIBRARIES})

在plugin_test目录下新建launch文件夹, 创建class_loader.launch文件, 复制下述内容.

    <launch>

        <!-- plugin params -->
        <param name="polygon_loader_v1/derive_class_1" value="polygon_plugins::Triangle" />
        <param name="polygon_loader_v1/derive_class_2" value="polygon_plugins::Square" />

        <node name="polygon_loader_v1"
             pkg="plugin_test" type="polygon_loader_v1" output="screen" />

    </launch>

编译成功后, 运行launch文件, 因为在代码中, 我们初始化了ros节点, 并且在launch文件中我们添加了ros parameter, 发起launch文件后, 会自动开启roscore, 输出会比较混乱, 应该会得到下述类似的输出.

    $ roslaunch plugin_test class_loader.launch

    ... ...

    auto-starting new master
    process[master]: started with pid [16890]
    ROS_MASTER_URI=http://localhost:11311

    setting /run_id to bfd33a96-9cf8-11e6-a0bb-78acc03c5a93
    process[rosout-1]: started with pid [16903]
    started core service [/rosout]
    process[polygon_loader_v1-2]: started with pid [16906]
    [ INFO] [1477650287.294727014]: The polygon (1 / 2) area: 43.30
    [ INFO] [1477650287.294864723]: The polygon (2 / 2) area: 100.00
    [ INFO] [1477650287.294899464]: Waiting "Ctrl + C"

上述代码都比较简单, 就不做过多说明了.

3. 进阶

pluginlib的源码见链接: https://github.com/ros/pluginlib . 打开include文件夹, 可以看得到, 其中仅包含少量的文件. 截图如下:


include

3.1 class_list_macros.h

其结构很清晰, 其中几个重要的宏申明于class_list_macros.h中, 定义如下:

    #include <class_loader/class_loader.h>
    /** 
     * @macro This version was deprecated in favor of PLUGINLIB_DECLARE_CLASS
     * @param - class_name - An alias for the class (no special characters allowed)  (IGNORED AS OF PLUGINLIB 1.9)
     * @param - class_type - The real class name with namespace qualifier (e.g. Animals::Lion)
     * @param - base_class_type - The real base class type from which class_type inherits
     */
    #define PLUGINLIB_REGISTER_CLASS(class_name, class_type, base_class_type) \
      CLASS_LOADER_REGISTER_CLASS_WITH_MESSAGE(class_type, base_class_type, "In file " __FILE__ " pluginlib WARNING: PLUGINLIB_REGISTER_CLASS is deprecated, please use PLUGINLIB_EXPORT_CLASS instead. You can run the script 'plugin_macro_update' provided with pluginlib in your package source folder to automatically and recursively update legacy macros. Base = base_class_type, Derived = derived_class_type")

    /** 
     * @macro This version is the most in use and requires package name in addition to fields in PLUGINLIB_REGISTER_CLASS 
     * @param - pkg - The package that exports the plugin (IGNORED AS OF PLUGINLIB 1.9)
     * @param - class_name - An alias for the class (no special characters allowed)  (IGNORED AS OF PLUGINLIB 1.9)
     * @param - class_type - The real class name with namespace qualifier (e.g. Animals::Lion)
     * @param - base_class_type - The real base class type from which class_type inherits
     */
    #define PLUGINLIB_DECLARE_CLASS(pkg, class_name, class_type, base_class_type) \
      CLASS_LOADER_REGISTER_CLASS_WITH_MESSAGE(class_type, base_class_type, "pluginlib WARNING: In file " __FILE__ " PLUGINLIB_DECLARE_CLASS is deprecated, please use PLUGINLIB_EXPORT_CLASS instead. You can run the script 'plugin_macro_update' provided with pluginlib in your package source folder to automatically and recursively update legacy macros.  Base = base_class_type, Derived = derived_class_type")

    /** 
     * @macro This version was only made possible with pluginlib 1.9 series. It's the easiest to use and now the official way of exporting classes.
     * @param - class_type - The real class name with namespace qualifier (e.g. Animals::Lion)
     * @param - base_class_type - The real base class type from which class_type inherits
     */
    #define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type) \
      CLASS_LOADER_REGISTER_CLASS(class_type, base_class_type);

3.2 class_desc.h

class_desc.h文件的定义如下, 其主要是用于保存前述xml文件中所编辑的关于plugin的内容.

      class ClassDesc
      {
        public:
          /**
           * @brief  Constructor for a ClassDesc
           * @param lookup_name The lookup name of the class 
           * @param derived_class The type of the derived class of the class
           * @param base_class The type of the class, corresponds to the type of the base class
           * @param package The package the class lives in
           * @param description A description for the class
           * @param library_name The name of the containing library for the class (not a full path!)
           * @param plugin_manifest_path The path to the plugin manifest file
           */
          ClassDesc(const std::string& lookup_name, const std::string& derived_class, const std::string& base_class, const std::string& package, 
              const std::string& description, const std::string& library_name, const std::string& plugin_manifest_path):
            lookup_name_(lookup_name), 
            derived_class_(derived_class),
            base_class_(base_class),
            package_(package),
            description_(description), 
            library_name_(library_name),
            resolved_library_path_("UNRESOLVED"),
            plugin_manifest_path_(plugin_manifest_path){}

          std::string lookup_name_;
          std::string derived_class_;
          std::string base_class_;
          std::string package_;
          std::string description_;
          std::string library_name_;
          std::string resolved_library_path_; //This is set by pluginlib::ClassLoader at load time
          std::string plugin_manifest_path_;
      };

3.2 class_loader

除了上述两部分外, 另外一个是与违例相关的类申明文件, pluginlib_exceptions.h. 当然, 其中最重要的部分, 是class loader. class_loader是pluginlib中最基础的部分. 完成在运行时从运行库中动态的加载已导入的C++类, 即插件, 以及创建这些类的对象. 一般而言, 当插件是为了non-ROS package所创建的时, 应用使用class loader; 而将插件导入到ROS package时, 应该使用pluginlib. class loader主要提供两个接口, 分别是class_loader::ClassLoader 和 class_loader::MultiLibraryClassLoader. 都提供了类似的接口, 不同之处在于, 前者仅能绑定单个库, 而后者可以绑定多个库. 基本应用示例如下:

    #include <class_loader/class_loader.h> // 包含头文件
    #include "MyBase.h" // 引入已声明的基类

    int main()
    {
      // 实例化一个class_loader::ClassLoader对象, 传入参数是需要导入库的完整路径以及名称
      class_loader::ClassLoader loader("libMyLibrary.so");
      // 获取由基类MyBase所定义接口的类
      std::vector<std::string> classes = loader.getAvailableClasses<MyBase>();
      for(unsigned int c = 0; c < classes.size(); ++c)
      {
        boost::shared_ptr<MyBase> plugin = loader.createInstance<MyBase>(classes[c]);
        plugin->someMethod();
        // plugin是局部变量, 离开花括弧作用域后将会自动析构
      }
    }

值得说明的几点:

  1. ClassLoader可以查询到具有某个基类的插件(或类), 并且实例化这些插件, 前提条件是这些插件提前注册并导入了, 即在实现文件末尾加入下述宏定义.

        CLASS_LOADER_REGISTER_CLASS(Derived, Base)
  2. 从上述示例用法中可以看到, 客户端的代码, 虽然不需要子类的具体定义, 但不可避免的是需要共同基类(即MyBase)的定义. 上述代码中可以看到, 查询可用插件和创建实例的两个接口, 均是模板函数. 如果你所给定的基类不对, 是不能够成功获取到任何东西.

  3. 允许某个类多次申明, 并具有不同的基类申明

  4. class_loader::ClassLoader 和 class_loader::MultiLibraryClassLoader的所有接口都是线程安全的.

  5. 模板函数中的模板, 都是静态判定的, 保证获取到的接口是类型准确的. 不会出现加载到具有不兼容接口的无效插件.

最后, 如果对class loader的具体实现感兴趣的朋友, 可以参看下述链接, http://wiki.ros.org/class_loader/Design , 并配合前面给出的Github上的源码进行理解.

【ROS-1】关于插件的编写与使用(pluginlib) pluginlib是一个c++库, 用来从一个ROS功能包中加载和卸载插件(plugin)。插件是指从运行时库中动态加载的类。通过使用Pluginlib,不必将某个应用程序显式地链接到包含某个类库,Pluginlib可以随时打开包含类的库,而不需要应用程序事先知道包含类定义的库或者头文件。 阅读详情

相关推荐

Python从zip文件里导入包

有时候为了节省空间,可以把包压缩成zip文件,这样方便管理,方便上传到网络上,也方便拷贝。但是有没有方法可以直接使用zip文件的包,而不需要解压出来呢?这是有的。 先创建一个目录如下: 然后把demo目录使用压缩软件,或者使用Python里的zip模块,就可以生成压缩文件mylib.zip。在目录demo中创建__init__.py文件,然后在文件里输入下面内容: #学习算法笔记-蔡军生(qq:9073204) #https://mysoft.blog.youkuaiyun.com/ #2020-1...

大坡3D软件开发 1632

ROS pluginlib步骤

1.创建插件 一般情况是有基类的,以move_base导航栈为例。其nav_core包下有几个头文件,这就是基类所在,其具体实现由继承类完成,基类的构造函数是protected 2.新建软件包 catkin_create_pkg package_name roscpp 基类包名 ...... 3. 继承类头文件要包含 基类 #include <基类包名/基类头文件名.h> 这里是因为头文件在/include/包名/头文件名。如果就在include文件夹里 不用包名就可以了 .cpp文件..

dwell548560的博客 737

ARM Memory Compiler实战指南:从参数配置到GDSII生成的全流程解析

本文详细解析了ARM Memory Compiler在SRAM设计中的全流程应用,从基础参数配置到GDSII文件生成。涵盖SRAM类型选择、核心参数配置策略、高级优化技巧及TSMC 28nm工艺下的实战案例,帮助IC设计工程师高效实现存储器模块的优化设计。

game4的博客 416

ROS-----pluginlib使用总结

pluginlib是一个C++库,可以实现为一个ROS包动态的加载和卸载插件。

倔强不倒翁的博客 1万+

基于ZYNQ7020芯片(黑金开发板AX7020)之AXI-FULL DDR的PL与PS交互操作。

在该工程中我们使用了PS端的串口接收功能,PS端串口接收和发送分别有一个64字节的FIFO,但是因为串口接收阈值设置为16,所以固定接收16个字节数据后才会发生中断。此测试工程得到以前知识的总结和各大网友的支持,只希望可以为学习的你更进一步,大家一起学习才是真的开心。加油,国产芯片之路。

landyjzlai的博客 3189

【React】1、React入门与概览(JSX语法)

React入门 文章目录React入门一、React全家桶1. React是什么?2. 谁开发的?3. 为什么要学?4. React的特点5. 学习React之前要掌握的JavaScript基础知识二、React 概览组件JSXVirtual DOM关于虚拟DOM:Data Flow三、React基本使用相关js库四、React JSXJSX 语法规则五、模块与组件、模块化与组件化的理解5.1 模块5.2 组件5.4 模块化5.5 组件化 一、React全家桶 React基础 React-Router(R

Coding and studying 1379

在ROS中利用pluginlib库生成插件并使用

在ROS中利用pluginlib库生成插件并使用

weixin_47962228的博客 1191

C#串口通信上位机开发实战:轻松实现硬件控制与数据交互

摘要:本文介绍如何使用C#开发串口通信上位机应用,实现与硬件设备(如传感器、PLC等)的数据交互。文章涵盖串口通信原理、开发环境配置、功能实现(串口连接管理、数据收发、实时显示)及UI设计,重点讲解SerialPort类的应用、多线程数据接收处理和错误优化。通过Windows Forms构建直观界面,帮助开发者快速掌握工业控制和自动化系统中的串口通信技术,为物联网和智能设备开发提供实用解决方案。全文约150字。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 3028

【ROS】使用pluginlib自定义costmap地图层

pluginlib是一个 C++ 库,用于从 ROS 包中加载和卸载插件。插件是从运行时库(即共享对象、动态链接库)加载的动态可加载类。使用 pluginlib,人们不必将他们的应用程序显式链接到包含类的库,相反,pluginlib 可以在任何时候打开一个包含导出类的库,而无需应用程序事先知道该库或包含类定义的头文件. 插件可用于在不需要应用程序源代码的情况下扩展/修改应用程序行为。

qq_52785580的博客 2274

Cadence OrCAD Capture原理图中为功能模块分配ROOM的方法

本文详解介绍原理图设计阶段为原理图模块分配ROOM的方法。

fydar的博客 1345

Codex 实战 Skills:用 Skill 自动识别并提取 PDF/图片表格数据,效率提升 10 倍

本文介绍如何构建一个多模态文件解析 Skill,用于自动识别和提取 PDF/图片中的表格数据,提升 AI 智能体处理非结构化文档的效率。文章分析了传统方法的局限性,提出分层解析架构(预处理、检测、提取推理、后处理),推荐技术栈包括 pdfplumber、OpenCV 和多模态大模型。详细说明了 Skill 的元数据定义、数据模型设计(使用 Pydantic)和核心实现流程,通过混合策略实现从复杂文档到结构化 JSON/Markdown 的转换,使 AI 代理具备"阅读"多模态文档的能力。

yueyeguzhuo的专栏 298

ROS中如何快速实现plugin插件

wiki百科:plugin插件 步骤: step1:创建基类 #ifndef PLUGINLIB_TUTORIALS__POLYGON_BASE_H_ #define PLUGINLIB_TUTORIALS__POLYGON_BASE_H_ namespace polygon_base { class RegularPolygon { public: virtual void initialize(double side_length) = 0; virtu

☜@_@达奚黑雁的博客 375

基于江协科技STM32创建HAL库工程模板

基于江协科技STM32入门教程创建的HAL库工程模板

2401_82728381的博客 1130

ROS源代码阅读(13)——Plugin

2021SC@SDUSC ROS源代码阅读(13)

qzyj99的博客 914

手把手教你学Simulink--基于Simulink的高增益DC-DC变换器仿真建模

特点高电压增益:可以在不使用变压器的情况下实现较大的电压升压比。适用于低电压源:如太阳能电池板、燃料电池等提供的低压直流电源。效率问题:设计时需特别注意提高效率,减少能量损失。挑战电路复杂性:通常涉及多个电感和电容,以及复杂的开关模式。元件选择:合适的元件参数对于达到理想性能至关重要。控制策略:确保高效稳定运行的同时,适应负载变化。首先明确要模拟的任务内容。实现特定的电压增益比(例如从24V升至380V)。根据预期的输入输出电压确定合适的电路拓扑和元件值。

MHD0815的博客 172

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

ROS 中 pluginlib 包的详细解析

pluginlib是 ROS 提供的一个强大的 C++ 库,旨在简化插件的编写、动态加载与卸载过程。插件在 ROS 中指的是可以在运行时加载的类,这些类被编译到动态链接库(如.so文件)中。使用pluginlib动态性:无需在编译时将插件类链接到应用程序中,可以在运行时根据需要加载。模块化:允许开发者在不修改应用程序源代码的前提下,扩展或修改应用行为。灵活性:支持多种插件类型,适用于不同的应用场景。通过pluginlib,开发者可以轻松地实现插件架构,使得系统更具扩展性和可维护性。

m0_73640344的博客 1193

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

ROS:pluginlib

ROS:pluginlib

立于皓月之边,不弱星光之势 1678

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

ROS使用(7)plugin

wu

qq_44632658的博客 1197

ROS的pluginlib学习总结一

在开发中需要使用到插件,因此学习了下pluginlib的一些使用,学习的还不够透彻,先记录一下这几天的学习结果。关于ROS中pluginlib的使用主要参考的是《》与《》这两篇文章。第一篇中讲述了一个示例,第二篇是ROS官方中对于pluginlib使用的一些解释的翻译。

YiYeZhiNian的博客 1417

创建和使用插件

ROS创建和使用插件

Shilong的博客 652

【ROS2】初级:客户端-创建和使用插件(C++)

目标:学习使用pluginlib创建和加载一个简单的插件。教程级别:初学者时间:20 分钟目录背景先决条件任务创建基类包创建插件包2.1插件的源代码2.2 插件声明 XML2.3 CMake 插件声明使用插件构建并运行摘要背景这个教程源自于 http://wiki.ros.org/pluginlib,以及编写和使用一个简单插件教程。pluginlib是一个 C++库,用于在...

cxyhjl的博客 1211

ROS学习记录(一)全局规划器Plugin插件

遇到这个问题的初衷是看了。

weixin_45863919的博客 2662

10.3.1 pluginlib使用

ROS入门 10.3.1 pluginlib使用 《ROS入门-理论与实践》视频教程镇楼 需求: 以插件的方式实现正多边形的相关计算。 实现流程: 准备; 创建基类; 创建插件类; 注册插件; 构建插件库; 使插件可用于ROS工具链; 配置xml 导出插件 使用插件; 执行。 1.准备 创建功能包xxx导入依赖: roscpp pluginlib。 在 VSCode中需要配置 .vascode/c_cpp_properties.json文件中关于 includepath 选项的设置。 {

赵虚左 602

ROS中插件plugin的简单使用方法

插件,如同其名字一样,第一次接触的时候让我想到了U盘或者USB线这类东西,它们和电脑没有关系,但是插入(挂载)电脑USB口后却可以正常使用,仿佛扩展了电脑的功能。软件中的插件也是类似的,插件化开发使得程序开发扩展性增强,并且不需要对于程序的框架做本质上的改变。插件的本质是创建一个第三方库在软件中来使用。 ROS中插件的创建步骤如下5步: 1)创建基类 2)创建插件 3)注册插件 4)编译插件 5)将新的插件添加到ROS的工具链当中 1.在ROS中创建插件 1)创建基类 先创建一个工作空间c

6472

ROS 2边学边练(20)-- 创建和使用插件(C++)

本篇介绍了ROS 2关于插件的一些内容,并举例说明。

DIANZI520SUA的专栏 1854
上一篇: <ROS> 机器人描述--URDF和XACRO
下一篇: <ROS>ROS Control之Transmission
小贝也沉默
博客等级 码龄16年 281粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值