最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網 會員登陸 & 注冊

像設計CPU一樣設計算法

2022-05-18 15:04 作者:西湖大學空中機器人  | 我要投稿

之前兩篇文章中,我們介紹了深度學習算法用于無人機的檢測以及可用于無人機視覺與控制算法研究的仿真平臺。今天我們要來看,無人機算法的開發(fā)與部署的過程中,會遇到的問題與解決方案。

在進入主題之前,首先問大家一個問題。

1.?修理收音機容易還是修理電腦容易?

沒有接觸過收音機的同學可能會說,收音機比電腦簡單多了,肯定是收音機好修理啊。其實不然,收音機內部都是電阻、三極管、電路板等,甚至一些收音機內都是貼片元件。若是沒有足夠的專業(yè)知識以及合適的修理工具,一般人什么都做不了,更不用談及修理。

相反的,電腦的復雜程度遠高于收音機,但是一般性電腦的修理卻是比收音機要容易。若是內存卡出了問題,只要更換內存卡就可以;若是硬盤出了問題,只要更換硬盤就可以。一句話來總結,哪里壞了換哪里,只需要簡單的插拔即可。

2.?高內聚、低耦合

在軟件工程里面,上述電腦的這種“易插拔”稱作“高內聚、低耦合”。同時,我們還要指出,像電腦內的CPU這類產品,所有電腦都在使用,但是卻不用知道其內部實現(xiàn)細節(jié),在主板上只要簡單的“插上”就能使用。這是因為,每個主板都會預留與CPU針腳的插槽,無論是何種CPU都遵循這個統(tǒng)一的接口來設計。所以CPU的設計是基于“接口”的設計,而不是針對“實現(xiàn)”的設計。

這個思想也同樣適用與軟件設計與算法設計。先舉一個反面例子,通常習慣用“面向過程”編程的同學,在開發(fā)中常遇到這種情況,修改一處的代碼會導致其他地方的代碼也出錯,像下面的動圖所示。所以在程序員也常被戲稱,一直在“寫B(tài)ug”。其實,這就是“收音機”式的編程。各個模塊相互依賴,難以維護。而我們想要的是“CPU”式的設計,編寫的算法能夠像CPU一樣,只需要簡單的“插拔”就能實現(xiàn)算法的修改、部署、升級,而不影響系統(tǒng)其他模塊。

(動圖原作者@我的鄰居全是貓,詳情請點擊下方知乎鏈接)

那什么是“CPU”式的編程或者算法開發(fā)呢?這就需要用到面向對象編程與設計模式。接下來,我們將給出一種算法開發(fā)的場景,來展示設計模式在算法開發(fā)與部署中的妙用。

3.?場景:多種算法,框架類似,但部分實現(xiàn)細節(jié)有差異

現(xiàn)在我們需要在無人機上實現(xiàn)不同的控制算法,為簡單起見,假定算法需求如下:

l 不同的算法所需的輸入不同,例如有的需要獲取無人機位置,有的需要獲取速度,加速度等

l 不同的算法,控制方式不同,如PID控制法,最優(yōu)控制法,模型預測法

l 控制輸出都需要經過速度限幅,最大速度為5m/s

設計方案A

UML圖如下所示


實例代碼如下所示,為簡化代碼,省略了內存管理,且將不同文件的代碼整合在一處并省略了源文件的代碼。

class ControlAlgorithmA { public: void ObtainControlInput(); // Obtain velocity void Control(); // PID control void VelocityLimit(); // v <= 5 m/s }; class ControlAlgorithmB { public: void ObtainControlInput(); // obtain position void Control(); // optimizing control void VelocityLimit(); // v <= 5 m/s }; class ControlAlgorithmC { public: void ObtainControlInput(); // obtain position and velocity void Control(); // model predictive control void VelocityLimit(); // v <= 5 m/s }; int main(int argc, char* argv[]) { ControlAlgorithmA* algorithm_a = new ControlAlgorithmA(); ControlAlgorithmB* algorithm_b = new ControlAlgorithmB(); ControlAlgorithmC* algorithm_c = new ControlAlgorithmC(); // run algorithm A algorithm_a->ObtainControlInput(); algorithm_a->Control(); algorithm_a->VelocityLimit(); // run algorithm B algorithm_b->ObtainControlInput(); algorithm_b->Control(); algorithm_b->VelocityLimit(); // run algorithm C algorithm_c->ObtainControlInput(); algorithm_c->Control(); algorithm_c->VelocityLimit(); return 0; }

三種算法具有相同的結構,用戶在使用三種算法時不得不從頭到尾一步步調用算法的各個步驟,并且當速度限幅發(fā)生改變,比如降低到3m/s,三種算法都要改動,且容易發(fā)生錯誤。

設計方案B——使用模板模式(Template Pattern)

UML圖如下所示

示例代碼如下

class ControlAlgorithm { public: void Template() { ObtainControlInput(); Control(); VelocityLimit(); } protected: virtual void ObtainControlInput() = 0; virtual void Control() = 0; void VelocityLimit(); // v <= 5 m/s }; class ControlAlgorithmA : public ControlAlgorithm { public: void ObtainControlInput() override; // Obtain velocity void Control() override; // PID control }; class ControlAlgorithmB : public ControlAlgorithm { public: void ObtainControlInput() override; // obtain position void Control() override; // optimizing control }; class ControlAlgorithmC : public ControlAlgorithm { public: void ObtainControlInput() override; // obtain position and velocity void Control() override; // model predictive control }; int main(int argc, char* argv[]) { // run algorithm A ControlAlgorithm* algorithm = new ControlAlgorithmA(); algorithm->Template(); // run algorithm B algorithm = new ControlAlgorithmB(); algorithm->Template(); // run algorithm C algorithm = new ControlAlgorithmC(); algorithm->Template(); return 0; }

ControlAlogrithm類在這里的作用就好像是提供了前文提到的“卡槽”,A,B,C三種算法就好像不同型號的CPU,雖然型號不同,內部實現(xiàn)不同,但是算法的“接口”是相同的。同時,ControlAlogrithm類在Template方法中定義了算法的骨架,算法的具體步驟則推遲到子類中(除了VelocityLimit,是所有子類都相同的)。模板模式使得子類可以不改變一個算法的結構的前提下對算法進行某些特定步驟的修改。

甚至,我們可以使用“工廠模式”或是“策略模式”(不在本篇文章中詳述)將三種算法進一步“隱藏”,客戶端甚至只需要“知道”ControlAlogrithm類,而不需要“知道”任意的算法,使得客戶端不依賴于任何算法,如下圖所示意。“Less Code, Less Bug”,客戶端“知道”的越少,“犯錯”的概率也就越小。

int main(int argc, char* argv[]) { // run algorithm A Factory* factory; ControlAlgorithm* algorithm = factory->CreateAlgorithm("A"); algorithm->Template(); // run algorithm B algorithm = factory->CreateAlgorithm("B"); algorithm->Template(); // run algorithm C algorithm = factory->CreateAlgorithm("C"); algorithm->Template(); return 0; }

4.?總結的話

通過使用“面向對象”和“設計模式”,我們可以開發(fā)并部署”CPU”式的算法/程序,通過基于“接口”的設計實現(xiàn)“易插拔”即“高內聚耦合”的特性,使得我們的算法可以非常復雜但易于維護、復用和拓展。關于更多的設計模式的使用,可以在參考資料中查詢。

本期是關于算法的設計。實際上在開發(fā)過程中,算法肯定需要不斷的修改,如何能快速知道修改完的代碼是否能正常運行,算法運算各階段結果是否準確?謹請關注下一期——算法的測試開發(fā)。

參考資料

[1] 程杰. 大話設計模式. 清華大學出版社, 2007.

[2] Gamma, Erich, et al. Elements of reusable object-oriented software. Vol. 99. Reading, Massachusetts: Addison-Wesley, 1995.

本文由西湖大學智能無人系統(tǒng)實驗室工程師陳華奔安原創(chuàng)

申請文章授權請聯(lián)系后臺相關運營人員

▌微信公眾號:空中機器人前沿

▌知乎:空中機器人前沿(本文鏈接:https://zhuanlan.zhihu.com/p/453593782?)

▌Youtube:Aerial robotics @ Westlake University

▌實驗室網站:https://shiyuzhao.westlake.edu.cn/? ?


像設計CPU一樣設計算法的評論 (共 條)

分享到微博請遵守國家法律
长沙县| 桑日县| 增城市| 康定县| 高安市| 长阳| 龙南县| 巍山| 富阳市| 扎囊县| 岚皋县| 徐州市| 临武县| 泗洪县| 云梦县| 偏关县| 广州市| 广宁县| 湖南省| 铜陵市| 德庆县| 三明市| 尉氏县| 通州区| 太湖县| 泰安市| 房产| 凉城县| 五大连池市| 静海县| 洪泽县| 仙游县| 遂川县| 安徽省| 会昌县| 图木舒克市| 砚山县| 田阳县| 甘德县| 璧山县| 高青县|