Autoware 筆記 No. 5——基於GNSS的定位


1. 前言

在之前的筆記No.2 中,我們直接采用ndt_matching的方法實現定位,但需要在打開rviz中,通過2D Pose Estimate指定初始位置。加入GNSS后,可以幫助ndt_matching找到初始位置,同時如果ndt_matching在運動過程中匹配失敗,GNSS可以幫助重定位。

在/ndt_matching算法中,有兩個條件使用GNSS重定位:

(1) 如果設置ndt_matching的config中設置了GNSS,而非Initial Pos,那么ndt_matching會在程序初始運行中采用GNSS作為初值;

(2) 在車輛運行過程中,當topic /ndt_stat中的score值大於600(與地圖匹配程度,值越大匹配的越差),同樣會使用GNSS重定位。

下面介紹干貨

 

 

2. GNSS讀入數據配置

我們采用某品牌的GNSS設備,通過串口讀入信息,所以首先在Autoware中設置為串口讀入,如下圖:

 

首先配置GNSS下的Serial GNSS的config,我們的串口GNSS設備的設備名稱為/dev/ttyS0,波特率為115200,設置成功后,點擊OK保存,然后點擊Serial GNSS選項,這時會提示錯誤:

ERROR: cannot launch node of type [nmea_navsat_driver/nmea_topic_serial_reader]: nmea_navsat_driver
ROS path [0]=/opt/ros/kinetic/share/ros
ROS path [1]=/home/a/autoware/ros/src
ROS path [2]=/home/a/catkin_ws/src
ROS path [3]=/opt/ros/kinetic/share
ERROR: cannot launch node of type [nmea_navsat_driver/nmea_topic_driver]: nmea_navsat_driver
ROS path [0]=/opt/ros/kinetic/share/ros
ROS path [1]=/home/a/autoware/ros/src
ROS path [2]=/home/a/catkin_ws/src
ROS path [3]=/opt/ros/kinetic/share

這時由於Autoware中的串口驅動沒有裝,根據autoware/ros/src/sensing/drivers/gnss/packages/nmea_navsat/scripts/README.md文件,需要下載驅動,運行

$ sudo apt-get install ros-kinetic-nmea-navsat-driver

如果不能更新,也可以從源碼下載,然后在autoware的工作空間下安裝,源碼的下載地址為:https://github.com/ros-drivers/nmea_navsat_driver.git,下載后切換到適合的kinetic分支即可運行。

這時在勾選Serial GNSS選項,通過查看topic /nmea_sentence,如果有輸出,且在sentence中有內容,即GNSS設備數據讀取成功。/nmea_sentence的數據內容:

---
header: 
  seq: 223
  stamp: 
    secs: 1568168594
    nsecs: 571928024
  frame_id: "/gps"
sentence: "$×××××,0,7847.600,360.000,1.663,0.720,0.0000000,0.0000000,0.00,0.000,0.000,0.000,0.000,0,0,0C*0C"

$*****代表nmea的標准,主流的標准有$GPGGA、$GPGSA、$GPGSV、$GPRMC、$GPVTG、$GPGLL。而我們采用的傳感器不是這些標准,所以需要自己寫nmea的數據解析。

不同的GNSS設備,sentence的中內容的標准會有不同。

如果想了解nmea,請參考博客:https://blog.csdn.net/jickjiang/article/details/79086202

 

3. 數據解析

Autoware的數據解析程序為nmea2tfpose包,由於我們采用的設備不是標准協議,但我們的協議和$GPGGA很接近,所以我們采用在$GPGGA的基礎上做了改進nmea2tfpose_core.cpp。

我們的修改思路為:

(1) 首先講基站的經緯度作為原點;

(2) 采用$GPGGA的方式,將經緯度坐標系映射到以基站為原點的平面坐標系;

(3) 通過tf變換,將基站為原點的坐標系的轉換到地圖坐標系。

我們沒有修改源碼,而是將nmea2tfpose包拿出來修改,編譯,然后單獨發布。

nmea2tfpose包最終發布的topic為/gnss_pose。查看/gnss_pose與/ndt_pose發布的數據是否基本一致,如果基本一致,那么成功。這里我公布出部分源碼,供大家參考(nmea2tfpose_core.cpp):

// 設置基站經緯度
geo_.set_origin(longitude_, latitude_);
    if (nmea.at(0) == "$×××××")  //heading pitch roll
    {
      // 直接讀取gnss中的roll, pitch, yaw
      position_time_ = stod(nmea.at(2));
      roll_ = stod(nmea.at(5)) * M_PI / 180.;
      pitch_ = -1 * stod(nmea.at(4)) * M_PI / 180.;
      yaw_ = -stod(nmea.at(3)) * M_PI / 180. + M_PI*2;
      
      //ROS_INFO("roll:%f, pitch:%f, yaw:%f.", roll_,pitch_,yaw_);
      
      // 根據GPGGA計算從經緯度到局部坐標系的映射
      double lat = stod(nmea.at(6));
      double lon = stod(nmea.at(7));
      double h = stod(nmea.at(8));
      geo_.set_llh_nmea_degrees(lat, lon, h);
    }
// 基站為原點坐標系到地圖坐標系的變換
tf::Pose tf_pose;
tf::poseMsgToTF(pose.pose, tf_pose);
tf::Quaternion q;
q.setRPY(0, 0, 3.2277); // 基站為原點坐標系與地圖坐標系夾角
tf::Transform tf_trans(q, tf::Vector3(-28.11, 10.79, 0));  // 基站為原點坐標系與地圖坐標系原點的差
tf_pose = tf_trans.inverse() * tf_pose;
tf::poseTFToMsg(tf_pose, pose.pose);

 

4. 結果

上面的代碼完成后,可以按照Autoware 筆記4的內容進行設置,這時無論車停在軌跡上的任何位置,可以直接找到位置,無需2D Pose Estimate指定初始位置。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM