對於rplidar 雷達,特點是360度掃瞄結果,無死角。而有時候,我們沒需要用到360度,只需要270度或者更少,這時需要在**裡對資料進行裁剪。
rplidar掃瞄角度的定義,如下圖:
a1型號:
a2型號:
通常我們選取是laser 正前方的扇型資料,從上圖可以看出
例如正面180度扇型資料,那麼選取的度數為0~90,270~359的資料
270度面的扇型資料,選取度數為0~135, 225~359的資料
回到**中
2.開啟node.cpp檔案,簡單看下邏輯
op_result = drv->grabscandata(nodes, count);
抓取乙個完整的0-360度的掃瞄資料
op_result = drv->ascendscandata(nodes, count); //nodes[0] 代表0度角的掃瞄資料,即nodes[90]代表90度角的掃瞄資料
按照掃瞄角度公升序方式將資料排序
這樣我們需要的資料就是nodes[0]~nodes[135],nodes[225]~nodes[359]。
然後用publish_scan將資料發布出去,
我所採取的方式是修改publish_scan函式,即將0~360的資料都傳入該函式,這樣有沒有設定angle_compensate都不影響發布的資料。
預設是angle_compensate = true,即傳入的資料是已經優化過的。我也試過外面進行角度裁剪,不過看掃瞄的結果,優化後的資料都堆到一起了,十分不準確。
如果想在main函式中進行裁剪,一定要搞清楚角度優化的原理。搞清楚下面變數的作用和優化演算法,待更新~~
const int angle_compensate_multiple = 1;
int angle_compensate_offset = 0;
rplidar_response_measurement_node_t angle_compensate_nodes[angle_compensate_nodes_count];
memset(angle_compensate_nodes, 0, angle_compensate_nodes_count*sizeof(rplidar_response_measurement_node_t));
int i = 0, j = 0;
for( ; i < count; i++ ) }}
檢視publish_scan函式:
void publish_scan(ros::publisher *pub,
rplidar_response_measurement_node_t *nodes, //掃瞄資料
size_t node_count, ros::time start, //掃瞄資料的個數,開始時間
double scan_time, bool inverted, //掃瞄時長,是否是倒置的
float angle_min, float angle_max, //最小角度和最大角度
std::string frame_id)
else
scan_msg.angle_increment =
(scan_msg.angle_max - scan_msg.angle_min) / (double)(node_count-1);
scan_msg.scan_time = scan_time;
scan_msg.time_increment = scan_time / (double)(node_count-1);
scan_msg.range_min = 0.15;
scan_msg.range_max = 8.0;
scan_msg.intensities.resize(node_count);
scan_msg.ranges.resize(node_count);
bool reverse_data = (!inverted && reversed) || (inverted && !reversed);
if (!reverse_data)
} else
}pub->publish(scan_msg);
}
修改後的**:
void publish_scan(ros::publisher *pub,
rplidar_response_measurement_node_t *nodes,
size_t node_count, ros::time start,
double scan_time, bool inverted,
float angle_min, float angle_max,
std::string frame_id)
else
scan_msg.angle_increment =
(scan_msg.angle_max - scan_msg.angle_min) / (double)(node_count-1);
scan_msg.scan_time = scan_time;
scan_msg.time_increment = scan_time / (double)(node_count-1);
scan_msg.range_min = 0.15;
scan_msg.range_max = 8.0;
scan_msg.intensities.resize(node_count);
scan_msg.ranges.resize(node_count);
bool reverse_data = (!inverted && reversed) || (inverted && !reversed); //修改後的**reverse_data就沒有用處了。
/* 將rplidar放到hokuyo的位置,角度資訊見上面的圖如下
0度/前
270度/左 rplidar的方向 90度/右
180度/後
kobuki接收到 laserscan scan_msg.ranges資料對應的角度資訊
180度/前
270度/左 kobuki的方向 90度/右
0度/後
要把 0~90度對應的node資料對映到 180~90度的scan_msg.ranges中
要把 90~180度對應的node資料對映到 90~0度的scan_msg.ranges中
要把 180~270度對應的node資料對映到 359~270度的scan_msg.ranges中
要把 270~359度對應的node資料對映到 270~180度的scan_msg.ranges中
*/const size_t degree_90 = 90; //固定值,演算法需要
const size_t degree_270 = 270; //固定值,演算法需要
const size_t left_degrees = 225; // 裁剪的範圍 保留資料225~359.
const size_t right_degrees = 135; // 裁剪的範圍 保留資料0~135.
//先全部置inf,注意:如果初始化是0,則表示範圍內無障礙,故不能置0。inf表示無資料
for (size_t i = 0; i < node_count; i++)
//將資料分別對應設定進去
for (size_t i = 0; i < node_count; i++)
else if (i > left_degrees)
else
} //發布出去
pub->publish(scan_msg);
}
講需要裁剪的角度放到launch檔案中,當作引數傳入,比在**中修改好很多
例如:在rplidar.launch檔案中加入
然後在main函式中增加
/**/
nh_private.param("cut_angle", cut_angle, false);
if (cut_angle)
/**/
就可以實現。 雷射雷達掃瞄角度裁剪
採用的是思嵐的雷射雷達a1,由於base的機構設計,需要對雷達進行角度裁剪。rplidar a1的掃瞄角度的定義如下 參考博文 我需要的掃瞄範圍是 0,在ros中,順時針為負,逆時針為正,裁剪方法 在node.cpp中void publish scan 函式中新增圖中的角度比較的語句即可.scan ...
自定義各種裁剪框 掃瞄框
由於專案的需要,我們需要三種裁剪框,矩形裁剪框相信大家都不陌生,矩形的比較簡單,思路 例如 正方形的裁剪框,我們只需要設定畫筆的顏色為半透明的,然後繪製上下左右四個矩形即可組成乙個正方形,那麼圓形的怎麼畫呢?如果是同樣的思路,那麼我們就需要畫兩個不規則的圖形,來組成圓,關鍵的地方就是那個半圓弧怎麼畫...
ArcGIS裁剪影像資料
這幾天處理一批gis資料,碰到影像資料比行政區域要大一點,這樣資料看上去不那麼美觀,需要把多餘的部分裁剪掉以便和其他圖層相匹配,幾經折騰終於把多餘的部分給裁剪掉了。arcmap中有專門的裁剪工具,在紅箱子工具箱arctoolbox data management tools raster clip,...