## Allan Variance (圖來源自[kalibr, imu noise model](https://github.com/ethz-asl/kalibr/wiki/IMU-Noise-Model)、[IMU 知識筆記](https://mapostech.com/imu/)) 具時間序列的資料其隨機誤差一般用 Allan Variance 分析, 概念是將資料依特定時間長度分段,各段分別取平均,再求相鄰段平均值的差值序列,最後計算差值序列的標準差。 <center> <image width=35% src=https://hackmd.io/_uploads/S1Wwc9zike.png> </center> 當用較短的時間長度分段時,對應至資料的高頻變化也就是高頻雜訊,用較長的時間長度分段時,對應至資料的低頻變化也就是低頻雜訊。 下圖典型 Allan Variance 分析圖(log-log AD plot) 用不同斜率來判斷是哪種類型的雜訊,下圖的縱軸:對差值序列的標準差取 log; 橫軸 : 對特定時間長度取 log. <center> <image width=70% src=https://hackmd.io/_uploads/Hy-r7jGo1x.png> </center> 查找方式 : 按照下方圖表, 先尋找數據上有多少斜率種類的擬合直線, 再依哪個特定時間段$\tau$ 求交點, 那就會是該雜訊的deviation. 如果想要找 ```Random Walk``` 雜訊種類的標準差, 需要找到 ```-1/2```斜率的擬合直線與 $\tau=1$ 求交點,對應出的 deviation. <center> <image width=70% src=https://hackmd.io/_uploads/BJPWfifjkg.png> </center> 在 kalibr 中, 會考慮 : 1. 量測雜訊 高頻雜訊, 標準差為 $\tau=1$ 與```1/2```斜率 random walk 的交點 2. bias雜訊 低頻雜訊, 標準差為 $\tau=3$ 與```-1/2```斜率 rate random walk 的交點 如下圖所示: <center> <image width=70% src=https://hackmd.io/_uploads/SyUuyTzjyg.png> </center> ### Reference 1. [kalibr, imu noise model](https://github.com/ethz-asl/kalibr/wiki/IMU-Noise-Model) 2. [IMU 知識筆記](https://mapostech.com/imu/) ## IMU Intrinsic Calibration Pipline 我們使用 [yahboom imu device](http://www.yahboom.net/study/IMU) + kalibr 推薦的 [allan_variance_ros](https://github.com/ori-drs/allan_variance_ros) 於 ROS1-noetic from kalibr docker. ### 環境建置 2025.03.03 #### yahboom imu device <center> <image width=55% src=https://hackmd.io/_uploads/BJ5552Go1l.png> </center> 首先按照 [yahboom imu device ](http://www.yahboom.net/study/IMU) 文件說明進行, 務必全部看完. 安裝檔只會用到 ```ros1_imu_ws.zip```, ```IMU standard PC software(V6.2.60)```. 以下只會提及重點~~~ 1. 設定 imu device 的採樣率至 200HZ 需要調整 baudrate . <center> <image width=75% src=https://hackmd.io/_uploads/HJhMooGi1e.png> </center> ros1 確認 imu 200hz 的方式 : <center> <image width=45% src=https://hackmd.io/_uploads/BJG4aozsJe.png> </center> 2. 關閉陀螺儀的自動校正(for 靜止狀態) 為了做 instric calibration, 所以需要進行調整 <center> <image width=75% src=https://hackmd.io/_uploads/Hk03jjziJl.png> </center> #### ROS1-noetic from kalibr docker <center> <image width=55% src=https://hackmd.io/_uploads/Hyd0q3Gjyl.png> </center> 首先先去 [kalibr installation](https://github.com/ethz-asl/kalibr/wiki/installation) 下載 ROS1-noetic from kalibr docker : <center> <image width=75% src=https://hackmd.io/_uploads/B1W6vofsyg.png> </center> 確認 docker images 名稱 by ```$docker images```, 因為接下來要以映像檔為主額外下載其他套件(包含 yahboom imu device deserializer). <center> <image width=75% src=https://hackmd.io/_uploads/ByfcuoMj1g.png> </center> 下載 yahboom imu device 的壓縮檔(python code) : ```ros1_imu_ws.zip``` . 安裝 docker by dockerfile : ::: spoiler 撰寫 dockerfile. ```shell= # Use ros1 + Ubuntu 20.04 as the base image from https://github.com/ethz-asl/kalibr/wiki/installation FROM kalibr MAINTAINER <your name> LABEL maintainer="<your email>" # Avoid interactive prompts during installation ARG DEBIAN_FRONTEND=noninteractive # Install development tools and dependencies RUN apt-get update && apt-get install -y \ vim \ git \ meld \ unzip \ python3-pip \ python3-tk \ udev \ lsof \ ros-$ROS_DISTRO-usb-cam \ ros-$ROS_DISTRO-imu-tools RUN pip install pyserial RUN git config --global diff.external meld # [kalibr] RUN echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc SHELL ["/bin/bash", "-c"] # [IMU] refer to http://www.yahboom.net/study/IMU # [IMU] 1-1. unzip ros1_imu_ws.zip [Retronix version] COPY ros1_imu_ws.zip /root/ RUN unzip /root/ros1_imu_ws.zip -d /root/ # [IMU] 1-2. Compile feature pack and add into enviroment path RUN source /opt/ros/noetic/setup.bash && \ cd /root/ros_imu_ws/ && \ catkin_make -j && \ cd src/scripts/ && \ sudo chmod 777 *.py && \ echo "source ~/ros_imu_ws/devel/setup.sh" >> ~/.bashrc && \ source ~/.bashrc # [alan variance] https://github.com/ori-drs/allan_variance_ros RUN cd /catkin_ws/src && \ git clone https://github.com/ori-drs/allan_variance_ros.git RUN cd /catkin_ws/ && \ source /opt/ros/noetic/setup.bash && catkin build allan_variance_ros && source devel/setup.bash # Set the default command to run when the container starts CMD ["bash"] ``` ::: #### 指令集 - 建置 dokcer 指令 for dockerfile: ```shell= docker build -t kalibr_ros1 . ``` 下指令的資料夾結構 : <image width=35% src=https://hackmd.io/_uploads/rJ5o0oMjJg.png> - 啟動 docker 的指令 : ```shell= docker run -it \ -e DISPLAY=$DISPLAY \ -e XAUTHORITY=/run/user/1000/gdm/Xauthority \ -v /run/user/1000/gdm/Xauthority:/run/user/1000/gdm/Xauthority \ -v /tmp/.X11-unix:/tmp/.X11-unix \ --device=/dev/video0:/dev/video0 \ --net=host \ --privileged \ kalibr_ros1 ``` - 啟動 yahboom imu 指令集 : ``` # 1. 啟動 imu 的環境 cd ~/WitImu_ws colcon build source ~/WitImu_ws/install/setup.bash # 2. 啟動 imu device roslaunch wit_ros_imu rviz_and_imu.launch # 3. 播放 imu roslaunch wit_ros_imu rviz_and_imu.launch & rostopic echo /wit/imu # 4. 錄製 imu roslaunch wit_ros_imu rviz_and_imu.launch & rosbag record -O imu_data.bag /wit/imu # 5. 查看 錄製.bag 的簡易資訊 rosbag info imu_data.bag ``` ros1 的 imu 通用格式 by ```rostopic echo /wit/imu``` <center> <image width=75% src=https://hackmd.io/_uploads/S1MUx2Giyx.png> </center> ### allan_variance_ros tool 1. 錄製靜置的 imu 長達 8hr~24hr 需先確認 imu 採樣頻率!!! ```shell= # 啟動 imu 的環境 cd ~/WitImu_ws colcon build source ~/WitImu_ws/install/setup.bash # 錄製 imu roslaunch wit_ros_imu rviz_and_imu.launch & rosbag record -O imu_data.bag /wit/imu ``` 2. [allan_variance_ros command](https://github.com/ori-drs/allan_variance_ros) ```shell= # 啟動 allan_variance_ros 環境 cd /catkin_ws source devel/setup.bash rosrun allan_variance_ros cookbag.py --input imu_data.bag --output cooked_rosbag.bag rosrun allan_variance_ros allan_variance . imu_config.yaml rosrun allan_variance_ros analysis.py --data allan_variance.csv ``` Note : imu_config.yaml 是自己配置的, 如下所述: <image width=55% src=https://hackmd.io/_uploads/By2Oz3fj1l.png> squence_time 可以藉由 ```rosbag info imu_data.bag``` 查看. 3. 輸出結果圖 量測雜訊的標準差為 ```t=1s``` 與 white noise fit line (slope is ```1/2```) 的交點. Bias雜訊的標準差為 ```t=3s``` 與 random rate fit line (slope is ```-1/2```) 的交點. - 加速度器 <image width=85% src=https://hackmd.io/_uploads/BkL5b6Giye.png> - 陀螺儀 <image width=85% src=https://hackmd.io/_uploads/BycsZ6fikg.png> - 三種雜訊種類 該工具會分析三種雜訊種類於imu上 : 分別是斜率 ```-1/2```的 random walk, 斜率```0```的 bias instability, 斜率 ```1/2```的 rate random walk. - 量測雜訊就是斜率 ```-1/2```的 random walk, 高頻雜訊, (對應至$\tau = 1$) - 零偏雜訊就是斜率```1/2```的 rate random walk, 低頻雜訊, (對應至$\tau = 3$) ![image](https://hackmd.io/_uploads/Bka8Enzo1x.png) - 擬合雜訊模型 for kalibr 外參校正使用 allan_variance_ros tool 可輸出 kalibr 所需格式. ```noise_density```就是量測雜訊的標準差. ![image](https://hackmd.io/_uploads/BJm_ThGoyx.png) <image width=65% src=https://hackmd.io/_uploads/SJfRbpzoke.png> - 需要注意的是 : ==通常會對雜訊標準差乘上10倍==, 再給 slam 使用以及外參標定流程喔 !!! ## Camera-IMU Extrinsic pipline 流程參考 [link](https://www.youtube.com/watch?v=rBT5O5TEOV4) 1. 執行 Docker 並共用資料夾 ```shell= FOLDER=/home/andrew/Documents/Code/SLAM/Calibration/data sudo docker run -it \ -e DISPLAY=$DISPLAY \ -e XAUTHORITY=/run/user/1000/gdm/Xauthority \ -v /run/user/1000/gdm/Xauthority:/run/user/1000/gdm/Xauthority \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -v "$FOLDER:/data" \ --net=host \ kalibr_allan ``` 2. (optional) 產生 apriltag 標定板 ```shell= # generate target.pdf cd kalibr/aslam_offline_calibration/kalibr/python python3 kalibr_create_target_pdf --type apriltag --nx 6 --ny 6 --tsize 0.02 --tspace 0.3 ``` 3. 拍攝錄製成 bag ```shell= rosbag record -O imu_april.bag /camera/color/image_raw /oak/right/image_rectified /camera/depth/image_raw /imu/data ``` <center> <image width=55% src=https://hackmd.io/_uploads/HJr6dz-sll.png> </center> 4. (optional) 雙目標定 ```shell= rosrun kalibr kalibr_calibrate_cameras --bag imu_stereo.bag --topics /camera/color/image_raw /oak/right/image_rectified --models pinhole-radtan pinhole-radtan --target april_6x6.yaml ``` 5. camera + imu 標定 ```shell= rosrun kalibr kalibr_calibrate_imu_camera --target april_6x6.yaml --imu imu_bmi270.yaml --imu-models calibrated --cam cam_april-camchain.yaml --bag imu_april.bag ``` :::spoiler 參數檔 - april_6x6.yaml <center> <image width=80% src=https://hackmd.io/_uploads/BJ17AG-iee.png> </center> - imu_bmi270.yaml 直接取自 allan_ros_tool, 記得對雜訊乘上倍數. i.g. 白雜訊 * 5, 隨機遊走 * 10 <center> <image width=50% src=https://hackmd.io/_uploads/rySdpf-jgx.png> </center> - (雙目) cam_april-camchain.yaml ```cam_overlaps``` 指的是哪些相機與當前相機共視. <center> <image width=100% src=https://hackmd.io/_uploads/SkLnAG-sxx.png> </center> - (單目) cam_april-camchain.yaml <center> <image width=100% src=https://hackmd.io/_uploads/BkbS1QWixl.png> </center> ::: ### 校正工程的細節 - 相機內參標定 盡量降低曝光時間, 減少 motion blur - IMU 內參標定 透過 allan variance ros 校正出來的雜訊變異量, 需要放大. 白雜訊 * 5, 隨機遊走 * 10. - 聯合標定 - 設定 sigma 為 1 進行校正 - 標定手法 : 三軸都要旋轉到, 不能 constant 角速度 - 驗證 - 相機 - projection error 是否在 1 pixel. - 投影點是否遵從高斯分布(橢圓形) 如果不遵從, 代表相機模型可能是錯的. 以下方圖示為例, 遵從高斯分佈. <center> <image width=55% src=https://hackmd.io/_uploads/rkRDjzWsxe.png> </center> - IMU - 採樣點是否是 unitform 如果採樣點不規則, 可能是 bandwidth 開不夠大. 以下方圖為例, imu 200 hz 正常運作. <center> <image width=45% src=https://hackmd.io/_uploads/ByDsizbole.png> </center> - 確認加速度與陀螺儀是否都在紅框內(3 sigma) 如果沒有, 代表imu內參沒有求好. 以下方圖示為例, 在紅框內代表正常. <center> <image width=65% src=https://hackmd.io/_uploads/SJoeoG-jgg.png> </center> - 檢查變化量是否夠低 以下方紅框為例, 變化量是低的. <center> <image width=85% src=https://hackmd.io/_uploads/ryQq9MWsge.png> </center> - IMU 內參的單位 ![image](https://hackmd.io/_uploads/rypcm7fSxg.png) ### Reference 1. https://blog.csdn.net/kanhao100/article/details/130073156 2. https://tomas789.medium.com/iphone-calibration-camera-imu-and-kalibr-33b8645fb0aa 3. https://hackmd.io/@PFABrcAkRWSshatDzBNr9w/rJvgZ91rE 4. https://blog.csdn.net/qq_41694024/article/details/130598248