设计模式_策略模式 更改激光雷达类型

slam 设计模式_策略模式

  • 1介绍
    • 1.1原始需求
    • 1.2 策略模式
      • 1.2.1策略模式介绍
      • 1.2.2 最终使用
      • 1.2.3 接口类(策略定义)
      • 1.2.4 使用类
    • 1.3新激光雷达加入
  • 2 其他实例

1介绍

slam中经常需要更改激光雷达适配算法,最近在学习设计模式,这里使用策略模式,做一些处理,纯粹瞎写,欢迎拍砖。

1.1原始需求

在不同的slam算法里面经常要做算法适配,会有传感器坐标系的适配、数据格式的适配,,激光雷达的类型也比较多,有些需要pcl中注册生成新的数据类型。
这里是激光雷达数据适配的一部分代码。
 void CloudConvert::Process(const sensor_msgs::PointCloud2::ConstPtr &msg,
​                               std::vector<point3D> &pcl_out){switch (lidar_type_){case LidarType::OUST64:Oust64Handler(msg);break;case LidarType::VELO32:VelodyneHandler(msg);break;case LidarType::ROBOSENSE16:RobosenseHandler(msg);break;case LidarType::PANDAR:PandarHandler(msg);break;default:LOG(ERROR) << "Error LiDAR Type: " << int(lidar_type_);break;}
​        pcl_out = cloud_out_;}

可以看到是swich case 的结构,那么下面用策略模式改一下。

1.2 策略模式

1.2.1策略模式介绍

策略模式是生成模式的一种,
1. 是为了维持逻辑稳定
2. 把需要变动的部分抽象成接口,纯虚函数,让实现类去继承他

一般需要三个类:使用类,接口类(策略定义)和实现类(策略实现)。

  1. 按照变化部分和稳定部分的切分,应该有一个类是不变的,我一般都认为是使用类
  2. 有一个策略类作为接口(纯虚函数),
  3. 另外是一个 策略实现类 是可变的;
    在使用的时候,生成相关的策略实现类,传递给使用类的构造函数。然后用多态,动态加载去调用相关的函数,代码如下:

1.2.2 最终使用

我们先看最终使用情况:

int main()
{
​	Strategy *strategy =  new Strategy(ROBOSENSE16); //接口类和实现类LidarProcess lidarProcess(strategy);// 上面两句可以合成一句  LidarProcess lidarProcess(new Strategy(ROBOSENSE16));
​	lidarProcess->process(msg); //msg 为激光雷达的数据结构
} 

1.2.3 接口类(策略定义)

接口(策略)类要做成纯虚类:

class  Stategy  {virtual int lidarPreprocess(const sensor_msgs::PointCloud2::ConstPtr &msg);	
}

1.2.4 使用类

使用类,这部分是不会改变的,有两点要求
第一:要包含接口类作为成员变量,构造函数要传入接口类对其初始化;
第二:类中应有方法,可操作接口类的方法,完成动态绑定。

class LidarProcess  {
​	Stategy  *stategy ;//void LidarProcess( StrategyFactory *strategyFactory){	 也可以用工厂方法生成对象//this->stategy = strategyFactory.creat(); //}void LidarProcess( Stategy *stategy){this->stategy = stategy;}void process(const sensor_msgs::PointCloud2::ConstPtr &msg  ){if(stategy!= nullptr)) //通常要判断是不是为空。
​		    stategy->lidarPreprocess(const sensor_msgs::PointCloud2::ConstPtr &msg);}
}

最后是策略实现类,继承接口,重写对应的方法。

class OUST64lidar:Stategy
{virtual int lidarPreprocess(const sensor_msgs::PointCloud2::ConstPtr &msg) override{}};class VELO32:Stategy{virtual int lidarPreprocess(const sensor_msgs::PointCloud2::ConstPtr &msg) override{}};class ROBOSENSE16:Stategy{virtual int lidarPreprocess(const sensor_msgs::PointCloud2::ConstPtr &msg) override{}};

1.3新激光雷达加入

1.新激光雷达加入,需要 新的类去继承Stategy,重写对应的函数

class NEWlidar:Stategy{virtual int lidarPreprocess(const sensor_msgs::PointCloud2::ConstPtr &msg) override{}
};
2.需要更改main函数的第一句,	
Strategy *strategy =  new Strategy(NEWlidar); //接口类和实现类

2 其他实例

//示例1
#include <iostream>
#include <string>
#include <memory>using namespace std;//高层策略接口
class Strategy
{
public:virtual double CalcPrice(double  goodsPrice){return 0;}
};//具体策略
//普通客户策略
class NormalCustomerStrategy : public Strategy
{
public:double CalcPrice(double  goodsPrice) override{//普通客户没有折扣std::cout<<"普通客户没有折扣"<<std::endl;return goodsPrice;}
};//老客户策略
class OldCustomerStrategy : public Strategy
{
public:double CalcPrice(double  goodsPrice) override{//老客户 统一折扣5%std::cout<<"老客户折扣5%"<<std::endl;return goodsPrice * (1 - 0.05);}
};//大客户策略
class LargeCustomerStrategy : public Strategy
{double CalcPrice(double  goodsPrice) override{//大客户 统一折扣10%std::cout<<"大客户折扣10%"<<std::endl;return goodsPrice * (1 - 0.1);}
};//策略上下文
class Price
{
public:Price(Strategy* strategy) : pStrategy(strategy){}double Quote(double goodsPrice){if(pStrategy != nullptr){return pStrategy->CalcPrice(goodsPrice);}return 0;}
private:std::unique_ptr<Strategy> pStrategy {nullptr};
};
int main()
{{Price price(new NormalCustomerStrategy);double goodsPrice = price.Quote(100);std::cout<<"普通客户最终价:"<<goodsPrice<<std::endl;}{Price price(new OldCustomerStrategy);double goodsPrice = price.Quote(100);std::cout<<"老客户最终价:"<<goodsPrice<<std::endl;}{Price price(new LargeCustomerStrategy);double goodsPrice = price.Quote(100);std::cout<<"大客户最终价:"<<goodsPrice<<std::endl;}return 0;
}
//示例2
#include <iostream>
#include <string>
#include <memory>using namespace std;//策略模式扩展方式
//1.扩展上下文:通过继承上下文方式,然后在子类中添加相关数据
//2.扩展策略算法:在具体策略算法中添加相关数据//高层策略接口
class PayStrategy
{
public://virtual void Pay(PayContext* pPayContext){} //c++ 没有反射 不能直接传入context 然后获取上下文相关数据 适用于扩展方式1virtual void Pay(const std::string& user, double money){}
};//具体策略
//人民币现金支付
class RMBCashStrategy : public PayStrategy
{
public:void Pay(const std::string& user, double money) override{std::cout<<user<<"人民币现金支付:"<<money<<std::endl;}
};//美元支付
class DollarCashStrategy : public PayStrategy
{
public:void Pay(const std::string& user, double money) override{std::cout<<user<<"美元现金支付:"<<money<<std::endl;}
};//RMB账户支付 扩展方式2
class RMBAccountStrategy : public PayStrategy
{
private:std::string account;
public:RMBAccountStrategy(std::string account) : account(account){}
public:void Pay(const std::string& user, double money) override{std::cout<<user<<"RMB账户"<<account<<"支付:"<<money<<std::endl;}
};//策略上下文
class PayContext
{
private:std::string user;double money;public:PayContext(std::string user, double money, PayStrategy* payStrategy) : user(user), money(money), pPayStrategy(payStrategy){}public:void PayNow(){if(pPayStrategy != nullptr){return pPayStrategy->Pay(this->user, this->money);}}private:std::unique_ptr<PayStrategy> pPayStrategy {nullptr};
};int main()
{{PayContext* payContext = new PayContext("张三", 100.0, new RMBCashStrategy());payContext->PayNow();}{PayContext* payContext = new PayContext("petter", 200.0, new DollarCashStrategy());payContext->PayNow();}{PayContext* payContext = new PayContext("李四", 300.0, new RMBAccountStrategy("123456789"));payContext->PayNow();}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/189522.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

熬夜会秃头——beta冲刺Day4

这个作业属于哪个课程2301-计算机学院-软件工程社区-CSDN社区云这个作业要求在哪里团队作业—beta冲刺事后诸葛亮-CSDN社区这个作业的目标记录beta冲刺Day4团队名称熬夜会秃头团队置顶集合随笔链接熬夜会秃头——Beta冲刺置顶随笔-CSDN社区 一、团队成员会议总结 1、成员工作进…

算法题:求所需的最小的书包数量(拓展拓展再拓展~)

算法题&#xff1a;求所需的最小的书包数量 现在有一种书包&#xff0c;这种书包只有两个书槽&#xff08;即最多只能放下两本书。&#xff09;&#xff0c;并且一个这种书包只能装下N千克的书。现在有一个数组&#xff0c;数组元素是每本书的重量&#xff08;千克&#xff09…

基于 HarmonyOS 的用户登录界面实现

基于 HarmonyOS 的用户登录界面实现 HarmonyOS 是由华为推出的一种全场景分布式操作系统&#xff0c;该系统为不同类型的设备提供了统一的开发框架和一致的用户体验。本文将介绍如何使用 HarmonyOS 开发框架实现一个简单的用户登录界面。 在 HarmonyOS 开发中&#xff0c;使用…

JIRA 基本使用

该页面可以&#xff1a; 查看个人基本信息以及归属的邮件组修改常用参数配置查看指给自己的 Open 问题查看自己最近的活动记录等 权限管理 Project 权限管理 JIRA 项目有三种通用权限方案&#xff1a; 公开权限方案&#xff08;默认禁止使用此方案&#xff09;&#xff1a…

nodejs微信小程序+python+PHP学科建设管理信息系统的设计与实现-计算机毕业设计推荐

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

Android adb:“more than one device/emulator“解决办法

文章目录 问题解决办法列出所有设备先选择设备&#xff0c;再进行命令 问题 adb.exe: more than one device/emulator原因就是当前已经连接多台设备。 解决办法 列出所有设备 adb devices如下&#xff1a;有多个设备 List of devices attached 2270000938 device 172…

Vue3 Router跳转传参

最近遇到这个问题router跳转传参&#xff0c;真是要了老命了。 根据网上各位大神给出的方法&#xff0c;试了 import { useRouter } from vue-routerconst router useRouter()//1. 无法跳转 router.push(name:,params:{})//2. 可以跳转, 但需要在定义router同时定义占位符&a…

Android --- Activity/Window/DecorView/ViewRootImpl的创建时机

自己看源码后的学习记录&#xff0c;仅供参考。 【Android】Activity/Window/DecorView/ViewRootImpl的创建时机1.Activity 的创建时机-> public static void main(String[] args)-> ActivityThread.performLaunchActivity&#xff08;&#xff09;// Activity 被创建的…

全栈冲刺 之 一天速成MySQL

一、为什么使用数据库 数据储存在哪里&#xff1f; 硬盘、网盘、U盘、光盘、内存&#xff08;临时存储&#xff09; 数据持久化 使用文件来进行存储&#xff0c;数据库也是一种文件&#xff0c;像excel &#xff0c;xml 这些都可以进行数据的存储&#xff0c;但大量数据操作…

高端网站设计公司 -蓝蓝设计数据可视化大屏服务

UI设计公司-蓝蓝设计&#xff08;北京兰亭妙微科技有限公司&#xff09;是一支由清华美院毕业的专业团队组成的设计公司。我们的设计师们在大屏科研信息软件UI设计领域拥有多年的工作经验和丰富的行业知识。我们对设计充满热爱&#xff0c;设计不仅是我们的专业和职业&#xff…

QML中支持切换语言时,对现有qml进行优化时可以使用正文中的正则表达式。匹配不带某字符串的行并且有中文

这个正则表达式&#xff0c;可以在qt中搜索查找到不带qsTr(标记的中文字符串。后续可以用在qml中写了中文又没加qsTr(标记但是又需要支持中英文切换时&#xff0c;搜索匹配到没加qsTr(标记地方&#xff0c;重新加上qsTr(标记。 注意&#xff1a;复制这个正则表达式使用时&…

行内元素和块级元素分别有哪些?有何区别?怎样转换?

行内元素和块级元素分别有哪些&#xff1f; 常见的块级元素&#xff1a; p、div、form、ul、li、ol、table、h1、h2、h3、h4、h5、h6、dl、dt、dd 常见的行级元素&#xff1a; span、a、img、button、input、select 有何区别&#xff1f; 块级元素&#xff1a; 总是在新行上…

[二分查找]LeetCode1964:找出到每个位置为止最长的有效障碍赛跑路线

本文涉及的基础知识点 二分查找算法合集 作者推荐 动态规划LeetCode2552&#xff1a;优化了6版的1324模式 题目 你打算构建一些障碍赛跑路线。给你一个 下标从 0 开始 的整数数组 obstacles &#xff0c;数组长度为 n &#xff0c;其中 obstacles[i] 表示第 i 个障碍的高度…

flutter开发实战-实现获取视频的缩略图封面video_thumbnail

flutter开发实战-实现获取视频的缩略图封面video_thumbnail 在很多时候&#xff0c;我们查看视频的时候&#xff0c;视频没有播放时候&#xff0c;会显示一张封面&#xff0c;可能封面没有配置图片&#xff0c;这时候就需要通过获取视频的缩略图来显示封面了。这里使用了video…

嵌入式软件工程师面试题——2025校招社招通用(十七)

说明&#xff1a; 面试群&#xff0c;群号&#xff1a; 228447240面试题来源于网络书籍&#xff0c;公司题目以及博主原创或修改&#xff08;题目大部分来源于各种公司&#xff09;&#xff1b;文中很多题目&#xff0c;或许大家直接编译器写完&#xff0c;1分钟就出结果了。但…

第0篇红队笔记-APT-HTB

nmap 80 port-web尝试 searchploit-无结果 资源隐写查看-无结果 135 port rpcclient rpcinfo.py rpcdump.py rpcmap.py rpcmap.py爆破UUID 查看该UUID的表代表的服务能搜到UUID的漏洞 IOXIDResolver提取IPv6地址 IPV6-nmap smb smb探测目录 文件下载 测试其他目录 zip文件…

Quirks(怪癖)模式是什么?它和 Standards(标准)模式有什么区别?

前言: "Quirks模式"和"Standards模式"是与HTML文档渲染模式相关的两种模式。它们影响着浏览器如何解释和渲染HTML和CSS。理解它们之间的区别对于前端开发者和网页设计师来说是至关重要的。本文将深入讨论Quirks模式和Standards模式的区别&#xff0c;以及它…

vscode如何在没有网络的情况下安装插件

vscode如何在没有网络的情况下安装插件 start 遇到没有网络的电脑&#xff0c;无法直接从插件市场安装vscode的插件。写一下 vscode 插件离线安装的方法. 解决方案 目标电脑没有可以安装插件的网络&#xff0c;那我们只能在有网络的环境下载好我们的插件。然后拷贝软件到无…

【Qt之QColor】

QColor是Qt框架中一个表示颜色的类&#xff0c;它提供了大量的方法进行颜色的构造、转换和操作。C示例如下&#xff1a; #include <QApplication> #include <QWidget> #include <QPainter> #include <QColor>class Example : public QWidget { public…