在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

關于MinBox障礙物邊框構建的干貨!

YB7m_Apollo_Dev ? 來源:lq ? 2018-12-06 16:23 ? 次閱讀

Apollo感知模塊具有識別障礙物和交通燈的能力,LiDAR利用點云感知,可以了解障礙物的位置、大小、類別、朝向、軌跡和速度等信息

Apollo解決的障礙物感知問題有:

·高精地圖ROI過濾器(HDMap ROI Filter)

·基于卷積神經網絡分割(CNNSegmentation)

·MinBox障礙物邊框構建(MinBoxBuilder)

·HM對象跟蹤(HM Object Tracker)等

Apollo視覺感知輸出的第一步是做detection(目標檢測)和分割,第二步是要把結果2D-to-3D,同時還有一個tracking(追蹤)的過程后,即完成了感知的主要輸出步驟。

其中,tracking是做時序,2D和3D結果也會做tracking,這是無人車做感知常有的pipeline(線性模型),有這樣的結果以后,就會輸出被感知物體的位置和速度等信息。

在障礙物邊框構建這一環節,開發者使用CNN Seg DL學習的方法,得到障礙物信息后,可使用MinBox的方法得到物體的2D框(最終邊界框),結合tracking結合相機圖像進行學習得到的物體邊界框,則可得到物體3D的邊界框。

以下是Apollo社區開發者朱炎亮在Github-Apollo-Note上分享的《如何構建MinBox障礙物邊框》,感謝他為我們在MinBox Builder這一步所做的詳細注解和釋疑。

面對復雜多變、快速迭代的開發環境,只有開放才會帶來進步,Apollo社區正在被開源的力量喚醒。

對象構建器組件為檢測到的障礙物建立一個邊界框。因為LiDAR傳感器的遮擋或距離,形成障礙物的點云可以是稀疏的,并且僅覆蓋一部分表面。因此,盒構建器將恢復給定多邊形點的完整邊界框。即使點云稀疏,邊界框的主要目的還是預估障礙物(例如,車輛)的方向。同樣地,邊框也用于可視化障礙物。

算法背后的想法是找到給定多邊形點邊緣的所有區域。在以下示例中,如果AB是邊緣,則Apollo將其他多邊形點投影到AB上,并建立具有最大距離的交點對,這是屬于邊框的邊緣之一。然后直接獲得邊界框的另一邊。通過迭代多邊形中的所有邊,如下圖所示,Apollo確定了一個6邊界邊框,將選擇具有最小面積的方案作為最終的邊界框。

我們從代碼入手,一步步解析障礙物邊框構建的流程。

上一步CNN分割與后期處理,可以得到LiDAR一定區域內的障礙物集群。接下來,我們將對這些障礙物集群建立其標定框。標定框的作用除了標識物體,還有一個作用就是標記障礙物的長length、寬width、高height。其中規定長length大于寬width,障礙物方向就是長的方向direction。

MinBox構建過程如下:

·計算障礙物2D投影(高空鳥瞰XY平面)下的多邊形polygon(如下圖B)。

·根據上述多邊形,計算最適邊框(如下圖C)。

大致的代碼框架如下:

1 /// file in apollo/modules/perception/obstacle/onboard/lidar_process_subnode.ccvoid LidarProcessSubnode::OnPointCloud(const sensor_msgs::PointCloud2& message) { /// call hdmap to get ROI 2 ... /// call roi_filter 3 ... /// call segmentor 4 ... /// call object builder 5 if (object_builder_ != nullptr) { 6 ObjectBuilderOptions object_builder_options; if (!object_builder_->Build(object_builder_options, &objects)) { 7 ... 8 } 9 } 10 }/// file in apollo/modules/perception/obstacle/lidar/object_builder/min_box/min_box.ccbool MinBoxObjectBuilder::Build(const ObjectBuilderOptions& options, std::vector* objects) { for (size_t i = 0; i < objects->size(); ++i) { if ((*objects)[i]) { BuildObject(options, (*objects)[i]); 11 } 12 } 13 }void MinBoxObjectBuilder::BuildObject(ObjectBuilderOptions options, ObjectPtr object) { ComputeGeometricFeature(options.ref_center, object); 14 }void MinBoxObjectBuilder::ComputeGeometricFeature(const Eigen::Vector3d& ref_ct, ObjectPtr obj) { // step 1: compute 2D xy plane's polygen15 ComputePolygon2dxy(obj); // step 2: construct box16 ReconstructPolygon(ref_ct, obj); 17 }

以上部分是MinBox障礙物邊框構建的主題框架代碼,構建的兩個過程分別在ComputePolygon2dxy

和ReconstructPolygon函數完成,下面我們就具體深入這兩個函數,詳細了解一下Apollo對障礙物構建的一個流程,和其中一些令人費解的代碼段。

Step 1. MinBox構建--計算2DXY平面投影

這個階段主要作用是障礙物集群做XY平面下的凸包多邊形計算,最終得到這個多邊形的一些角點。第一部分相對比較簡單,沒什么難點,計算凸包是調用plc庫的ConvexHull組件(具體請參考pcl::ConvexHull)。

Apollo的凸包計算代碼如下:

1 /// file in apollo/modules/perception/obstacle/lidar/object_builder/min_box/min_box.ccvoid MinBoxObjectBuilder::ComputePolygon2dxy(ObjectPtr obj) { 2 ... 3 ConvexHull2DXY hull; 4 hull.setInputCloud(pcd_xy); 5 hull.setDimension(2); 6 std::vector poly_vt; 7 PointCloudPtr plane_hull(new PointCloud); 8 hull.Reconstruct2dxy(plane_hull, &poly_vt); if (poly_vt.size() == 1u) { 9 std::vector ind(poly_vt[0].vertices.begin(), poly_vt[0].vertices.end()); TransformPointCloud(plane_hull, ind, &obj->polygon); 10 } else { 11 ... 12 } 13 }/// file in apollo/modules/perception/common/convex_hullxy.htemplate class ConvexHull2DXY : public pcl::ConvexHull {public:14 void Reconstruct2dxy(PointCloudPtr hull, std::vector *polygons) { PerformReconstruction2dxy(hull, polygons, true); 15 } void PerformReconstruction2dxy(PointCloudPtr hull, std::vector *polygons, bool fill_polygon_data = false) { 16 coordT *points = reinterpret_cast(calloc(indices_->size() * dimension, sizeof(coordT))); // step1. Build input data, using appropriate projection17 int j = 0; for (size_t i = 0; i < indices_->size(); ++i, j += dimension) { 18 points[j + 0] = static_cast(input_->points[(*indices_)[i]].x); 19 points[j + 1] = static_cast(input_->points[(*indices_)[i]].y); 20 } // step2. Compute convex hull21 int exitcode = qh_new_qhull(dimension, static_cast(indices_->size()), points, ismalloc, const_cast(flags), outfile, errfile); 22 std::vector, Eigen::aligned_allocator>> idx_points(num_vertices); 23 FORALLvertices { 24 hull->points[i] = input_->points[(*indices_)[qh_pointid(vertex->point)]]; 25 idx_points[i].first = qh_pointid(vertex->point); 26 ++i; 27 } // step3. Sort28 Eigen::Vector4f centroid; pcl::compute3DCentroid(*hull, centroid); for (size_t j = 0; j < hull->points.size(); j++) { 29 idx_points[j].second[0] = hull->points[j].x - centroid[0]; 30 idx_points[j].second[1] = hull->points[j].y - centroid[1]; 31 } std::sort(idx_points.begin(), idx_points.end(), pcl::comparePoints2D); 32 polygons->resize(1); 33 (*polygons)[0].vertices.resize(hull->points.size()); for (int j = 0; j < static_cast(hull->points.size()); j++) { 34 hull->points[j] = input_->points[(*indices_)[idx_points[j].first]]; 35 (*polygons)[0].vertices[j] = static_cast(j); 36 } 37 } 38 }

從以上代碼的注釋中,我們可以清楚地了解到這個多邊形頂點的求解流程,具體函數由PerformReconstruction2dxy函數完成,這個函數其實跟pcl庫自帶的很像pcl::ConvexHull::performReconstruction2D/Line76,其實Apollo開發人員幾乎將pcl庫的performReconstruction2D原封不動地搬了過來,僅去掉了一些冗余的信息。

這個過程主要有:

1. 構建輸入數據,將輸入的點云復制到coordT *points做處理。

2. 計算障礙物點云的凸包,得到的結果是多邊形頂點。調用qh_new_qhull函數。

3. 頂點排序,從pcl::comparePoints2D/Line59

可以看到排序是角度越大越靠前,atan2函數的結果是[-pi,pi]。所以就相當于是順 時針對頂點進行排序。

上圖為計算多邊形交點的流程示意圖

該過程并不繁瑣,這里不再深入解釋每個模塊。

Step 2. MinBox構建--邊框構建

邊框構建的邏輯,大致是針對過程中得到的多邊形的每一條邊。將剩下的所有點都投影到這條邊上,就可以計算邊框Box的一條邊長度(最遠的兩個投影點距離),同時選擇距離該條邊最遠的點計算Box的高,這樣就可以得到一個Box(上圖case1-7分別是以這個多邊形7條邊作投影得到的7個Box),最終選擇Box面積最小的邊框作為障礙物的邊框。

上圖中case7得到的Box面積最小,所以case7中的Box就是最終障礙物的邊框。當邊框確定以后,就可以得到障礙物的長度length(大邊長),寬度(小邊長),方向(大邊上對應的方向),高度(點云的平均高度,CNN分割與后期處理階段得到)。

但是在此過程中,不得不承認有部分代碼塊相對難理解,而且出現了很多實際問題來優化這個過程。這里我將對這些問題一一進行解釋。

根據代碼,先簡單地將這個過程歸結為2步:

1. 投影邊長的選擇(為什么要選擇?因為背對lidar那一側的點云是稀疏的,那一側的多邊形頂點是不可靠的,不用來計算Box)。

2. 每個投影邊長計算Box。

在進入正式的代碼詳解以前,這里有幾個知識點需要了解。

假設向量a=(x0,y0),向量b=(x1,y1),那么有:

·兩個向量的點乘, a·b = x0x1 + y0y1\。

·計算向量a在向量b上的投影: v = a·b/(b^2)·b,投影點的坐標就是v+(b.x, b.y)。

·兩個向量的叉乘, axb = |a|·|b|sin(theta) = x0y1 - x1y0,叉乘方向與ab平面垂直,遵循右手法則。叉乘模大小另一層意義是: ab向量構成的平行四邊形面積。

如果兩個向量a,b共起點,那么axb小于0,那么a to b的逆時針夾角大于180度;等于則共線;大于0,a to b的逆時針方向夾角小于180度。

接下來正式解剖

ReconstructPolygon構建的代碼:

(1) Step1:投影邊長的選擇

1 /// file in apollo/modules/perception/obstacle/lidar/object_builder/min_box/min_box.ccvoid MinBoxObjectBuilder::ReconstructPolygon(const Eigen::Vector3d& ref_ct, ObjectPtr obj) { // compute max_point and min_point 2 size_t max_point_index = 0; size_t min_point_index = 0; 3 Eigen::Vector3d p; 4 p[0] = obj->polygon.points[0].x; 5 p[1] = obj->polygon.points[0].y; 6 p[2] = obj->polygon.points[0].z; 7 Eigen::Vector3d max_point = p - ref_ct; 8 Eigen::Vector3d min_point = p - ref_ct; for (size_t i = 1; i < obj->polygon.points.size(); ++i) { 9 Eigen::Vector3d p; 10 p[0] = obj->polygon.points[i].x; 11 p[1] = obj->polygon.points[i].y; 12 p[2] = obj->polygon.points[i].z; 13 Eigen::Vector3d ray = p - ref_ct; // clock direction14 if (max_point[0] * ray[1] - ray[0] * max_point[1] < EPSILON) { 15 ? ? ? ?max_point = ray; 16 ? ? ? ?max_point_index = i; 17 ? ? ?} ? ?// unclock direction18 ? ? ?if (min_point[0] * ray[1] - ray[0] * min_point[1] > EPSILON) { 19 min_point = ray; 20 min_point_index = i; 21 } 22 } 23 }

以上代碼內容為計算min_point和max_point兩個角點,該角點到底是什么?其中關于EPSILON的比較條件到底代表什么?

有一個前提我們已經在polygons多邊形角點計算中可知:obj的polygon中所有角點都是順時針按照arctan角度由大到小排序。

此過程可以通過下圖了解其作用:

圖中叉乘與0(EPSILON)的大小是根據前面提到的,兩個向量的逆時針夾角。從上圖中可以清晰地看到:max_point和min_point就代表了LiDAR能檢測到障礙物的兩個極端點。

1 /// file in apollo/modules/perception/obstacle/lidar/object_builder/min_box/min_box.ccvoid MinBoxObjectBuilder::ReconstructPolygon(const Eigen::Vector3d& ref_ct, ObjectPtr obj) { // compute max_point and min_point 2 ... // compute valid edge 3 Eigen::Vector3d line = max_point - min_point; double total_len = 0; double max_dis = 0; bool has_out = false; for (size_t i = min_point_index, count = 0; count < obj->polygon.points.size(); i = (i + 1) % obj->polygon.points.size(), ++count) { //Eigen::Vector3d p_x = obj->polygon.point[i] 4 size_t j = (i + 1) % obj->polygon.points.size(); if (j != min_point_index && j != max_point_index) { // Eigen::Vector3d p = obj->polygon.points[j]; 5 Eigen::Vector3d ray = p - min_point; if (line[0] * ray[1] - ray[0] * line[1] < EPSILON) { 6 ? ? ? ? ?... 7 ? ? ? ?}else { 8 ? ? ? ? ?... 9 ? ? ? ?} 10 ? ? ?} else if ((i == min_point_index && j == max_point_index) || (i == max_point_index && j == min_point_index)) { 11 ? ? ? ?... 12 ? ? ?} else if (j == min_point_index || j == max_point_index) { ? ? ?// Eigen::Vector3d p = obj->polygon.points[j];13 Eigen::Vector3d ray = p_x - min_point; if (line[0] * ray[1] - ray[0] * line[1] < EPSILON) { 14 ? ? ? ? ?... 15 ? ? ? ?} else { 16 ? ? ? ? ?... 17 ? ? ? ?} 18 ? ? ?} 19 ? ?} 20 ?}

當計算得到max_point和min_point后就需要執行這段代碼,這段代碼可能令人費解的原因為——為什么需要對每條邊做一個條件篩選?

請看下圖:

上圖中,A演示了這段代碼對一個汽車的點云多邊形進行處理,最后的處理結果可以看到只有Edge45、Edge56、Edge67是有效的,最終會被計入total_len和max_dist。并且,相對應的邊都是在line(max_point-min_point)這條分界線的一側,同時也是靠近LiDAR這一側。

這說明靠近LiDAR這一側點云檢測效果好,邊穩定;而背離LiDAR那一側,會因為遮擋原因,往往很難(有時候不可能)得到真正的頂點,如上圖B所示。

(2) Step2:投影邊長Box計算

投影邊長Box計算由ComputeAreaAlongOneEdge函數完成,下面我們分析這個函數的代碼:

1 /// file in apollo/modules/perception/obstacle/lidar/object_builder/min_box/min_box.ccdouble MinBoxObjectBuilder::ComputeAreaAlongOneEdge( 2 ObjectPtr obj, size_t first_in_point, Eigen::Vector3d* center, double* lenth, double* width, Eigen::Vector3d* dir) { // first for 3 std::vector ns; 4 Eigen::Vector3d v(0.0, 0.0, 0.0); // 記錄以(first_in_point,first_in_point+1)兩個定點為邊,所有點投影,距離這條邊最遠的那個點 5 Eigen::Vector3d vn(0.0, 0.0, 0.0); // 最遠的點在(first_in_point,first_in_point+1)這條邊上的投影坐標 6 Eigen::Vector3d n(0.0, 0.0, 0.0); // 用于臨時存儲 7 double len = 0; double wid = 0; size_t index = (first_in_point + 1) % obj->polygon.points.size(); for (size_t i = 0; i < obj->polygon.points.size(); ++i) { if (i != first_in_point && i != index) { // o = obj->polygon.points[i] 8 // a = obj->polygon.points[first_in_point] 9 // b = obj->polygon.points[first_in_point+1]10 // 計算向量ao在ab向量上的投影,根據公式:k = ao·ab/(ab^2), 計算投影點坐標,根據公式k·ab+(ab.x, ab.y)11 double k = ((a[0] - o[0]) * (b[0] - a[0]) + (a[1] - o[1]) * (b[1] - a[1])); 12 k = k / ((b[0] - a[0]) * (b[0] - a[0]) + (b[1] - a[1]) * (b[1] - a[1])); 13 k = k * -1; 14 n[0] = (b[0] - a[0]) * k + a[0]; 15 n[1] = (b[1] - a[1]) * k + a[1]; 16 n[2] = 0; // 計算由ab作為邊,o作為頂點的平行四邊形的面積,利用公式|ao x ab|,叉乘的模就是四邊形的面積,17 Eigen::Vector3d edge1 = o - b; 18 Eigen::Vector3d edge2 = a - b; double height = fabs(edge1[0] * edge2[1] - edge2[0] * edge1[1]); // 利用公式: 面積/length(ab)就是ab邊上的高,即o到ab邊的垂直距離, 記錄最大的高19 height = height / sqrt(edge2[0] * edge2[0] + edge2[1] * edge2[1]); if (height > wid) { 20 wid = height; 21 v = o; 22 vn = n; 23 } 24 } else { 25 ... 26 } 27 ns.push_back(n); 28 } 29 }

從以上部分代碼可以看出,ComputeAreaAlongOneEdge函數接受的輸入包括多邊形頂點集合,起始邊first_in_point。代碼將以first_in_point和first_in_point+1兩個頂點構建一條邊,將集合中其他點都投影到這條邊上,并計算頂點距離這條邊的高——也就是垂直距離。

最終的結果會保存到ns中。代碼中,k的計算利用了兩個向量點乘來計算投影點的性質;height的計算利用了兩個向量叉乘的模等于兩個向量組成的四邊形面積的性質。

1 /// file in apollo/modules/perception/obstacle/lidar/object_builder/min_box/min_box.ccdouble MinBoxObjectBuilder::ComputeAreaAlongOneEdge( // first for 2 ... // second for 3 size_t point_num1 = 0; size_t point_num2 = 0; // 遍歷first_in_point和first_in_point+1兩個點以外的,其他點的投影高,選擇height最大的點,來一起組成Box 4 // 這兩個for循環是尋找ab邊上相聚最遠的投影點,因為要把所有點都包括到Box中,所以Box沿著ab邊的邊長就是最遠兩個點的距離,可以參考邊框構建。 5 for (size_t i = 0; i < ns.size() - 1; ++i) { 6 ? ? ?Eigen::Vector3d p1 = ns[i]; ? ?for (size_t j = i + 1; j < ns.size(); ++j) { 7 ? ? ? ?Eigen::Vector3d p2 = ns[j]; ? ? ?double dist = sqrt((p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1])); ? ? ?if (dist > len) { 8 len = dist; 9 point_num1 = i; 10 point_num2 = j; 11 } 12 } 13 } // vp1和vp2代表了Box的ab邊對邊的那條邊的兩個頂點,分別在v的兩側,方向和ab方向一致。14 Eigen::Vector3d vp1 = v + ns[point_num1] - vn; 15 Eigen::Vector3d vp2 = v + ns[point_num2] - vn; // 計算中心點和面積16 (*center) = (vp1 + vp2 + ns[point_num1] + ns[point_num2]) / 4; 17 (*center)[2] = obj->polygon.points[0].z; if (len > wid) { 18 *dir = ns[point_num2] - ns[point_num1]; 19 } else { 20 *dir = vp1 - ns[point_num1]; 21 } 22 *lenth = len > wid ? len : wid; 23 *width = len > wid ? wid : len; return (*lenth) * (*width); 24 }

剩下的代碼就是計算Box的四個頂點坐標,以及它的面積Area。

綜上所述,Box經過上述(1)(2)兩個階段,可以很清晰地得到每條有效邊(靠近lidar一側,在min_point和max_point之間)對應的Box四個頂點坐標、寬、高。最終選擇Box面積最小的作為障礙物預測Box。

整個過程的代碼部分相對較難理解,經過本節的學習,相信各位應該對MinBox邊框的構建有了一定了解。

自Apollo平臺開放已來,我們收到了大量開發者的咨詢和反饋,越來越多開發者基于Apollo擦出了更多的火花,并愿意將自己的成果貢獻出來,這充分體現了Apollo『貢獻越多,獲得越多』的開源精神。為此我們開設了『開發者說』板塊,希望開發者們能夠踴躍投稿,更好地為廣大自動駕駛開發者營造一個共享交流的平臺!

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 神經網絡
    +關注

    關注

    42

    文章

    4771

    瀏覽量

    100763
  • 函數
    +關注

    關注

    3

    文章

    4331

    瀏覽量

    62610
  • 無人車
    +關注

    關注

    1

    文章

    302

    瀏覽量

    36475

原文標題:開發者說丨Apollo感知解析之MinBox障礙物邊框構建

文章出處:【微信號:Apollo_Developers,微信公眾號:Apollo開發者社區】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    遇到障礙物自動返回?

    為什么有些東西,遇到障礙物會自動返回,是哪一種傳感器嗎?哪里有沒有這類的電路圖介紹下,非常感謝
    發表于 09-10 21:14

    設計完PCB后走線不能躲避障礙物時什么情況

    本帖最后由 gk320830 于 2015-3-8 20:36 編輯 設計完PCB后走線不能躲避障礙物時什么情況?已經設置了躲避障礙物還是不能躲避
    發表于 12-20 08:47

    求教 障礙物感應類開關

    本帖最后由 gk320830 于 2015-3-8 14:20 編輯 急需用到2米內障礙物感應器,帶開關功能或者高手幫忙設計個輔助開關電路,24V電源供電,多謝
    發表于 03-07 21:58

    基于單片機的道路障礙物系統,新人求教

    我想要做一個道路障礙物檢測系統。就是在路面上安一個檢測器,一旦有障礙物擋住,且在路上停留一段時間,就發射信號報警,使二極管發光。現在我想請教一下是不是檢測用紅外線好一點,延時用單片機程序大概要怎么寫?電路什么的怎么連啊?求大神解答
    發表于 03-10 13:33

    障礙物時 語音提示 前方危險,請注意。

    障礙物時語音提示前方危險,請注意。語音模塊是isd1820單片機51 求幫忙
    發表于 02-24 21:43

    基于labview機器視覺的障礙物時別

    通過攝像頭對周圍環境信息的實時采集,如果當鏡頭前方出現障礙物時候,以一定的方式(聲音或振動之類的)反饋出來。主要考慮的是實現盲人室內導盲作用,不需要太過于考慮實際使用,只要能實現判定到障礙物,自動提醒就行啦。怎么判定前方出現障礙物
    發表于 03-14 07:58

    新人求教AD中Pullback(障礙物)到底是一個什么概念或作用?

    ,即如果設置的障礙物值為20mil,那么在板的邊框外面有20mil的覆銅,在邊框的里面也有20mil的覆銅。”2、“Pullback”,是在內電層邊緣設置的一個閉合的去銅邊界,以保證內電層邊界距離PCB
    發表于 11-04 11:27

    請問Infrared Proximity Sensor如何檢測前方是否有障礙物

    Infrared Proximity Sensor如何檢測前方是否有障礙物
    發表于 11-06 07:57

    檢測障礙物有什么什么傳感器?

    檢測障礙物有什么什么傳感器,用紅外反射還是超聲波測距,或者還有其他傳感器?
    發表于 11-08 06:33

    匯編語言程序設計案例—動態顯示/障礙物檢測/障礙物方位檢測

    匯編語言程序設計案例1—動態顯示/障礙物檢測/障礙物方位檢測 10-1.  LED數碼管顯示原理10-2.  案例分析1(2位學號顯示)10-3.  案例分析2(簡易按鍵搶答)10-4.
    發表于 03-23 12:15 ?38次下載

    障礙物檢測實驗

    障礙物檢測實驗 一、實驗目的“旋風”小車在運動過程中要成功避開障礙物必須在一定距離外就探測到障礙物。在小車上探測障礙物
    發表于 03-23 10:47 ?2838次閱讀
    <b class='flag-5'>障礙物</b>檢測實驗

    障礙物方位檢測實驗

    障礙物方位檢測實驗 一、實驗目的小車在運動中要成功避開障礙物,除了要檢測是否有障礙物外,還需要判斷障礙物的方位,以便小
    發表于 03-23 10:48 ?2002次閱讀
    <b class='flag-5'>障礙物</b>方位檢測實驗

    使用IR模塊的障礙物檢測器

    電子發燒友網站提供《使用IR模塊的障礙物檢測器.zip》資料免費下載
    發表于 11-14 11:31 ?0次下載
    使用IR模塊的<b class='flag-5'>障礙物</b>檢測器

    如何讓Arduino使用雷達避開障礙物

    電子發燒友網站提供《如何讓Arduino使用雷達避開障礙物.zip》資料免費下載
    發表于 06-26 14:58 ?1次下載
    如何讓Arduino使用雷達避開<b class='flag-5'>障礙物</b>

    基于點云的3D障礙物檢測介紹

    基于點云的3D障礙物檢測 主要有以下步驟: 點云數據的處理 基于點云的障礙物分割 障礙物邊框構建 點云到圖像平面的投影 點云數據的處理 KI
    的頭像 發表于 06-26 10:22 ?968次閱讀
    基于點云的3D<b class='flag-5'>障礙物</b>檢測介紹
    主站蜘蛛池模板: 日本日本69xxxx| 国产高清精品自在久久| 伊人手机在线观看| 拍真实国产伦偷精品| 最新版天堂资源官网| 福利一级片| 亚洲丁香| 成年人网站在线| 视频在线观看网站免费| 无内丝袜透明在线播放| 成人欧美一区二区三区的电影| 激情综合五月天丁香婷婷| 一区二区三区电影| 国模啪啪一区二区三区| 国产美女作爱全过程免费视频| 99精品久久99久久久久久| 久久99热狠狠色精品一区| 九九精品国产| 五月天激情综合网| 97色伦人人| 中文字幕亚洲区| 欧美成人aaa大片| 久久夜夜肉肉热热日日| 一级毛毛片毛片毛片毛片在线看| 黄色毛片免费网站| 亚洲酒色1314狠狠做| 上课被同桌强行摸下面小黄文| 永久免费精品影视网站| 亚洲 丝袜 制服 欧美 另类| 米奇久久| www.射| 色视频在线观看免费| 天天爱夜夜| 亚洲综合激情九月婷婷| 4虎 影视 免费| 男女一进一出抽搐免费视频| 激情五月播播| 黄 在线| 玖玖在线| 最新黄色在线| 猛操网|