ipa 功能包調試,分區算法,覆蓋算法測試

參考

wiki 流網絡 flow network 解釋

相關文章

ipa 分區算法?ipa 分區算法總結,部分算法圖解

環境

ubuntu20,ros 版本 noetic

運行測試

按照 readme 提示進行測試,跳過第一個步驟,并不需要 turtlebot3。

執行第三個 launch 報錯:

看下 room_exploration_client.launch 文件

<?xml version="1.0"?>
<launch><arg name="env_pack" default="$(find cob_default_env_config)" /><arg name="robot_env" default="$(optenv ROBOT_ENV !!NO_ROBOT_ENV_SET!!)"/><arg name="robot_radius" default="0.5"/><arg name="coverage_radius" default="0.5"/><arg name="use_test_maps" default="true"/><!--  --><node ns="room_exploration" pkg="ipa_room_exploration" type="room_exploration_client" name="room_exploration_client" output="screen"><rosparam file="$(arg env_pack)/envs/$(arg robot_env)/map.yaml" command="load" /><param name="env_pack" value="$(arg env_pack)"/><param name="robot_env" value="$(arg robot_env)"/><param name="robot_radius" value="$(arg robot_radius)"/><param name="coverage_radius" value="$(arg coverage_radius)"/><param name="use_test_maps" value="$(arg use_test_maps)"/></node></launch>

env_pack:ipa 的配置功能包,實踐中將程序和系統配置分離,相關功能配置可能是在項目中專門配置功能包中。

robot_env:機器環境,在 env_pack 包中,對多個機器(差速輪底盤,阿克曼底盤等)有多個不同的配置,需要根據機器分別配置參數。

robot_radius:???作用

coverage_radius:機器的覆蓋半徑。

use_test_maps:是否用 ipa 官方的測試地圖。

默認的配置功能包是 cob_default_env_config ,我們自己的項目中不存在這個功能包,所以要創建一個新功能包來完成 ipa 配置功能包即可。

在 ipa_coverage_planning 文件包內創建 ipa_env 功能包,用 tree 查看目錄如下

?  ipa_coverage_planning git:(develop) ? tree -L 1
.
├── ipa_building_msgs
├── ipa_building_navigation
├── ipa_coverage_planning
├── ipa_env
├── ipa_room_exploration
├── ipa_room_segmentation
└── README.md

ipa_env 包目錄如下:

第 3 個 launch 指令執行需要修改 env_pack 參數值,如下:

roslaunch ipa_room_exploration room_exploration_client.launch env_pack:=ipa_env robot_env:=ipa_robot use_test_maps:=false

執行后依舊報錯:

room_exploration_client.launch 的 env_pack 默認值修改為存在的其他功能包名,如下:

<arg name="env_pack" default="$(find ipa_room_exploration)" />

執行后沒有“not found cob_default_env_config” 的錯誤了。

!!!注意!!!

這里說明 xml 中標簽 <arg> 的默認值執行是在終端賦值之前的執行的!

但有了其他問題,rosparam 找不到 map.yaml 文件:

在 map.yaml 文件目錄下執行 pwd 查看路徑:

路徑是正確的。

仔細看看 xml,發現 file 是用 $(arg env_pack) 拼接的,說明變量 env_pack 需要包含 ipa 配置功能包在系統中的絕對路徑,而我們的傳參僅僅傳遞了 ipa 配置功能包名。

修改 launch 如下,讓 file 自動尋找 env_pack 功能包在系統的絕對路徑,下面只顯示修改的部分:

  <arg name="env_pack" default="ipa_room_exploration" /><node ns="room_exploration" pkg="ipa_room_exploration" type="room_exploration_client" name="room_exploration_client" output="screen"><rosparam file="$(find $(arg env_pack))/envs/$(arg robot_env)/map.yaml" command="load" /><param name="env_pack" value="$(find env_pack)"/></node>

再執行 launch,map.yaml 文件已經可以找到了,但出現新問題,xml 中 $() 不讓嵌套使用,報語法錯誤。゚(TヮT)゚。

最后還是改成下面這樣:

<?xml version="1.0"?>
<launch><arg name="env_pack" default="$(find ipa_env)" /><arg name="robot_env" default="$(optenv ROBOT_ENV !!NO_ROBOT_ENV_SET!!)"/><arg name="robot_radius" default="0.5"/><arg name="coverage_radius" default="0.5"/><arg name="use_test_maps" default="true"/><!--  --><node ns="room_exploration" pkg="ipa_room_exploration" type="room_exploration_client" name="room_exploration_client" output="screen"><rosparam file="$(arg env_pack)/envs/$(arg robot_env)/map.yaml" command="load" /><param name="env_pack" value="$(arg env_pack)"/><param name="robot_env" value="$(arg robot_env)"/><param name="robot_radius" value="$(arg robot_radius)"/><param name="coverage_radius" value="$(arg coverage_radius)"/><param name="use_test_maps" value="$(arg use_test_maps)"/></node></launch>

執行 launch 也不需要修改 env_pack 變量值了:

roslaunch ipa_room_exploration room_exploration_client.launch robot_env:=ipa_robot use_test_maps:=false

程序運行成功!

測試地圖
ipa 默認覆蓋算法

覆蓋算法測試

ipa_room_exploration/ros/launch/room_exploration_action_server_params.yaml 文件中的 room_exploration_algorithm 參數來選擇覆蓋算法。重啟 ipa 服務端,重新加載參數,執行

roslaunch ipa_room_exploration room_exploration_action_server.launch

執行后發現覆蓋路徑無明顯變化。

服務端 log 如下:

log 顯示啟動 server.launch 后,覆蓋算法已經修改為 6 局部能量最小覆蓋算法。

注意這里的 room_exploration/path_planning_algorithm 的 room_exploration 并非參數空間前綴,而是代碼這么寫的。一開始還被誤導以為是參數空間名對不上導致的問題。

之后再啟動 client.launch,觸發了動態參數服務器,將覆蓋算法改為了 8,牛耕算法變種。

ipa_room_exploration/ros/src/room_exploration_action_client.cpp 的 121 行發現這段代碼,這里創建了動態參數服務器的客戶端,修改了參數:

屏蔽這段代碼,編譯 ipa_room_exploration 功能包,重新執行服務器 launch 和客戶端 launch。

成功執行了局部能量最小覆蓋算法!

ipa 新覆蓋算法

下面展示所有的覆蓋算法路徑效果,這里的測試僅修改了 room_exploration_algorithm 服務器參數,其他參數是官方默認參數

  • room_exploration_algorithm 參數值之 grid point explorator

對應論文的 Grid-based Traveling Salesman Coverage Path Planning 基于柵格旅行商覆蓋路徑算法,用 TSP 旅行商算法來計算地圖中所有空閑柵格的遍歷順序。

該算法十分耗時,作者甚至給它做了個進度條,用一張 gif 來感受一下有多慢:

ipa TSP 遍歷覆蓋算法

  • room_exploration_algorithm 參數值之 boustrophedon explorator

對應論文的 Boustrophedon Coverage Path Planning 牛耕覆蓋路徑算法

ipa 牛耕覆蓋算法

  • room_exploration_algorithm 參數值之 neural network explorator

神經網絡覆蓋算法

ipa 神經網絡覆蓋算法

  • room_exploration_algorithm 參數值之 convexSPP explorator

Convex Sensor Placement Coverage Path Planning 凸傳感器放置覆蓋路徑算法

Log 有點多 ...

ipa 凸包 SPP 覆蓋算法

  • room_exploration_algorithm 參數值之 flowNetwork explorator

論文參考文獻和源碼中都找不到相關論文。注釋有這么一句:

This class provides a coverage path planning algorithm based on a flow network.

Wiki 對流網絡 flow network 的解釋如下(有些資料叫 network flow 網絡流):
在圖論中,流網絡是一個有向圖,每條邊都有一個容量,每條邊接收一個流。邊的流量不能超過邊的容量。在運籌學 operations research 中,有向圖通常稱為網絡,頂點稱為節點,邊稱為弧。流必須滿足流入節點的流量等于流出節點的流量的限制,除非它是只有流出的源 S,或者只有流入的匯 t。

流網絡,源 S,匯 t

Log 刷屏非常多,似乎在第三方庫中,源碼搜索不到相關日志。程序陷入死循環一直沒有結束,該算法應該未完成。

  • room_exploration_algorithm 參數值之 energyFunctional explorator

對應論文 Grid-based Local Energy Minimization 基于柵格的局部能量最小算法

ipa 局部能量最小覆蓋算法

  • room_exploration_algorithm 參數值之 voronoi explorator

對應論文 Contour Line-based Coverage Path Planning 基于輪廓線的覆蓋路徑算法

執行后沒有規劃成功,服務端 log:

把服務器參數 revisit_areas 設置為 true,再次測試...還是規劃失敗。

客戶端 log:

沒有其他 log 提示了,初步判斷是地圖沒有封閉空間導致的,給地圖增加一圈黑邊(障礙物)再測試。

規劃成功!說明用 voronoi explorator 算法需要地圖有封閉邊界!

ipa 輪廓線覆蓋算法

  • room_exploration_algorithm 參數值之 boustrophedon variant explorator

牛耕法變種,改進了牛耕法中細胞分解后,對相同主軸的分區進行合并,減少區域的碎片化。沒找到對應的論文信息。

ipa 牛耕法變種覆蓋算法

分區算法測試

分區算法在 ipa_room_segmentation 功能包中,也是分為客戶端和服務端兩部分運行:

服務端 room_segmentation_action_server.launch 和客戶端 room_segmentation_action_client.launch

分區算法的參數配置在 ipa_room_segmentation/ros/launch/room_segmentation_action_server_params.yaml 中。

同樣,客戶端代碼也修改了動態參數服務器的參數,先屏蔽了 ipa_room_segmentation/ros/src/room_segmentation_client.cpp 的部分代碼:

編譯后分別運行服務端和客戶端的 launch。

測試的地圖不對,測試的還是官方的測試地圖:

ipa 分區測試默認地圖

而我的地圖是:

ipa 分區測試用戶地圖

從 log 看參數配置的生效了。再看看分區客戶端代碼是怎么寫的...

客戶端是直接把測試地圖名寫入一個 vector 變量 map_names 中,然后在 for 循環中在指定地址獲取相應的地圖地址,把地圖轉為地圖話題數據,再裝入 goal 中發送給服務端。

流程大概如下:


int main(int argc, char **argv)
{ros::init(argc, argv, "room_segmentation_client");ros::NodeHandle nh;// map namesstd::vector< std::string > map_names;map_names.push_back("lab_ipa"); // 這就是測試的第一張默認地圖map_names.push_back("lab_c_scan");... // 加了很多地圖for (size_t image_index = 0; image_index<map_names.size(); ++image_index) {// 在 ipa_room_segmentation 功能包的指定位置搜索地圖std::string image_filename = ros::package::getPath("ipa_room_segmentation") + "/common/files/test_maps/" + map_names[image_index] + ".png";cv::Mat map = cv::imread(image_filename.c_str(), 0); // cv 讀地圖...cv_image.toImageMsg(labeling); // 數據轉換actionlib::SimpleActionClient<ipa_building_msgs::MapSegmentationAction> ac("room_segmentation_server", true);... // goal 數據裝包ac.sendGoal(goal); // 目標發送到服務端bool finished_before_timeout = ac.waitForResult(ros::Duration()); // 等待結果if (finished_before_timeout) {... // 數據轉換到 cv 格式cv::imshow("segmentation", colour_segmented_map); // cv 顯示地圖cv::waitKey(); // 敲空格測試下一張地圖}} // forreturn 0;
}

所以只需要修改客戶端的測試地圖名稱和測試地圖所在的路徑即可。

根據自己的測試環境修改這兩部分代碼,編譯后測試 ok。

下面展示所有的分割算法分區效果,這里的測試僅修改了 room_segmentation_algorithm 服務器參數,其他參數是官方默認參數

  • room_segmentation_algorithm 參數值之 morphological segmentation

對應論文的 Morphological Segmentation 形態分割算法

ipa 形態分割算法

  • room_segmentation_algorithm 參數值之 distance segmentation

對應論文 Distance Transform-based Segmentation 距離變換分割算法

ipa 距離變換分割算法

  • room_segmentation_algorithm 參數值之 Voronoi segmentation

對應論文 Voronoi Graph-based Segmentation Voronoi 圖分割算法

ipa Voronoi 圖分割算法

  • room_segmentation_algorithm 參數值之 semantic segmentation

在《Room Segmentation: Survey, Implementation, and Analysis.》稱為Feature-based Segmentation 特征/語義分割

ipa 語義分割算法

  • room_segmentation_algorithm 參數值之 voronoi random field segmentation

對應論文 Voronoi Random Fields Segmentation Voronoi 隨機勢場分割

ipa Voronoi 隨機勢場分割算法

  • room_segmentation_algorithm 參數值之 passthrough segmentation

不分割算法,正如其名...

ipa 不分割算法

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/11100.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/11100.shtml
英文地址,請注明出處:http://en.pswp.cn/web/11100.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vue element checkbox的實現

實現多選非常簡單: 手動添加一個el-table-column&#xff0c;設type屬性為selection即可&#xff1b;默認情況下若內容過多會折行顯示&#xff0c;若需要單行顯示可以使用show-overflow-tooltip屬性&#xff0c;它接受一個Boolean&#xff0c;為true時多余的內容會在 hover 時以…

Java8 快速實現List轉map 、分組、過濾等操作

Java 8 是 Java 編程語言的一個重要版本&#xff0c;它引入了許多新特性和改進&#xff0c;使得 Java 開發變得更加高效和現代。 下面我們就來使用Java8 快速實現List轉map 、分組、過濾等操作。 定義1個用戶對象 public class User {private Integer id;private String nam…

計算機通信

一.進程和線程的區別? 1. 進程是資源分配的最小單位, 線程是cpu進行調度的最小單位。 2. 一個進程可以看做一個運行的程序, 一個進程中可以包含多個線程, 線程在進程內執行。 3. 多進程是指操作系統能同時運行多個任務&#xff08;程序&#xff09;&#xff0c;多線程是指在同…

數據挖掘原理與應用------分類預測

在數據挖掘和機器學習領域&#xff0c;TPR&#xff08;True Positive Rate&#xff09;是指在實際為陽性的情況下&#xff0c;模型正確預測為陽性的比例。TPR也被稱為靈敏度&#xff08;Sensitivity&#xff09;或召回率&#xff08;Recall&#xff09;。它是評估分類模型性能的…

【Linux】探索 Linux du 命令:管理磁盤空間的利器

給我一個擁抱 給我肩膀靠靠 你真的不需要 對我那么好 思念就像毒藥 讓人受不了的煎熬 我會迷戀上癮賴在你懷抱 &#x1f3b5; 陶鈺玉《深夜地下鐵》 在 Linux 系統管理中&#xff0c;磁盤空間管理是一項基礎而重要的任務。du&#xff08;disk usage&#…

如何解決IntelliJ IDEA中pom.xml依賴項引發的安全漏洞黃線警告問題

背景 在開發過程中&#xff0c;當我們在pom.xml文件中添加依賴項時&#xff0c;經常會發現IntelliJ IDEA報出黃色警告線條&#xff0c;提示存在潛在的安全漏洞。警告的具體展現形式如下&#xff1a; 解決方案 首先&#xff0c;打開設置菜單界面&#xff0c;接著選擇編輯器選…

vue3土味情話pinia可以持久保存再次修改App樣式

我是不是你最疼愛的人-失去愛的城市 <template><div class"talk"><button click"getLoveTalk">土味情話</button><ul><li v-for"talk in talkStore.talkList" :key"talk.id">{{ talk.title }}<…

用 Supabase CLI 進行本地開發環境搭建

文章目錄 &#xff08;零&#xff09;前言&#xff08;一&#xff09;Supabase CLI&#xff08;1.1&#xff09;安裝 Scoop&#xff08;1.2&#xff09;用 Scoop 安裝 Supabase CLI &#xff08;二&#xff09;本地項目環境&#xff08;2.1&#xff09;初始化項目&#xff08;2…

基于gin框架的文件上傳(逐行解析)

基于gin框架的文件上傳(逐行解析)記錄一下使用gin框架完成一個文件上傳的功能&#xff0c;一下是實現該功能的代碼&#xff0c;適合小白&#xff0c;代碼都有逐行解釋&#xff01; app.go: package routerimport ("chat/service""github.com/gin-gonic/gin&qu…

網絡工程師練習題

網絡工程師練習題 網橋怎樣知道網絡端口連接了那些網站?如果從端口收到一個數據幀,則將其源地址記入該端口的數據庫當網橋連接的局域網出現環路時怎么辦?運行生成樹協議阻塞一部分端口。使用IEEE 802.1q協議,最多可以配置4094個VLAN。VLAN中繼協議(VTP)有不同的工作模式,…

C++異常詳解

文章目錄 前言一、回顧C語言二、異常的概念三、異常的使用1.異常的拋出和捕獲2.異常的重新捕獲 三.異常安全與異常規范1.異常安全2.異常規范 四.自定義異常體系五.C標準庫的異常體系六.異常優缺點練習題總結 前言 在本篇文章中&#xff0c;我們將會詳細介紹一下有關C異常的講解…

微服務架構:注冊中心 Eureka、ZooKeeper、Consul、Nacos的選型對比詳解

微服務架構&#xff08;Microservices Architecture&#xff09;是一種基于服務拆分的分布式架構模式&#xff0c;旨在將復雜的單體應用程序拆分為一組更小、更獨立的服務單元。這些服務單元可以獨立開發、測試、部署&#xff0c;并使用不同的技術棧和編程語言。它們通過輕量級…

[華為OD] C卷 dfs 特殊加密算法 100

題目&#xff1a; 有一種特殊的加密算法&#xff0c;明文為一段數字串&#xff0c;經過密碼本查找轉換&#xff0c;生成另一段密文數字串。 規則如下 1?明文為一段數字串由0-9組成 2.密碼本為數字0-9組成的二維數組 3?需要按明文串的數字順序在密碼本里找到同樣的數字串…

PUBG非升級實用槍皮-部分盤點

藏匿處的黑貨箱武器需要耗費高額成本才能升級 對于像我這樣的日常休閑玩家來說是一筆不小的&#xff08;巨大的&#xff01;&#xff09;負擔 其實有許多普通非升級槍皮也是不錯的選擇 今天就來盤點一下我自己日常在用的普通皮 來看看你是不是也在用一樣的 &#xff08;僅是盤點…

【OceanBase診斷調優】—— 租戶資源統計項及其查詢方法

本文主要介紹 OceanBase 數據庫中租戶資源統計項及其查詢方法。 適用版本 OceanBase 數據庫 V4.1.x、V4.2.x 版本。 CPU 資源統計項 邏輯 CPU 使用率&#xff08;線程處理請求的時間占比&#xff09;。 通過虛擬表 __all_virtual_sysstat 在 SYS 系統租戶下&#xff0c;查看…

AtCoder Beginner Contest 308 A題 New Scheme

A題&#xff1a;New Scheme 標簽&#xff1a;模擬 題意&#xff1a;給定 8 8 8個數的序列&#xff0c;詢問這些數是否滿足以下條件&#xff1a; 在 100 100 100到 675 675 675之間且能被 25 25 25整除序列是單調非遞減的 題解&#xff1a;按題意模擬判斷就好了。 代碼&#…

09.zabbix自定義模塊并使用

zabbix自定義模塊并使用 根據tcp的11中狀態獲取值&#xff0c;進行批量配置監控項 [rootyunlong66 ~]# cat /etc/zabbix/zabbix_agentd.d/tcp.conf UserParameterESTABLISHED,netstat -antp |grep -c ESTABLISHED UserParameterSYN_SENT,netstat -antp |grep -c SYN_SENT Use…

Obsidian/Typora設置圖床

在obsidian中默認圖片是保存在本地的&#xff0c;但是在要導出文檔上傳到網上時&#xff0c;由于圖片保存在本地&#xff0c;會出現無法加載圖片的問題。 這里引用的一段話&#xff1a; 這里使用picgo-core和gitee實現圖床功能&#xff0c; 參考1&#xff1a; Ubuntu下PicGO配…

Github學習

1.Git與Github 區別: Git是一個分布式版本控制系統&#xff0c;簡單的說就是一個軟件&#xff0c;用于記錄一個或若干個文件內容變化&#xff0c;以便將來查閱特點版本修訂情況的軟件。 Github是一個為用戶提高Git服務的網站&#xff0c;簡單說就是一個可以放代碼的地方。Gi…

C語言 | Leetcode C語言題解之第85題最大矩形

題目&#xff1a; 題解&#xff1a; int maximalRectangle(char** matrix, int matrixSize, int* matrixColSize) {int m matrixSize;if (m 0) {return 0;}int n matrixColSize[0];int left[m][n];memset(left, 0, sizeof(left));for (int i 0; i < m; i) {for (int j …