Radar detection (AutowareAuto)
이 글은 위의 AutowareClass2020의 Radar perception 강좌를 기반으로 실행 해본 결과를 기록 했습니다.
Continental의 ARS408 Radar 센서 데이터를 읽고 ROS2 node를 이용해서 object messages로 publish하는 방법을 설명합니다. 검출된 object들은 RVIZ2에 표시합니다.
Radar는 mmWave 대역의 전파를 송출해서 물체를 감지하는 센서로 요즘 스마트 크루즈 컨트롤을 지원하는 대부분의 차량에 장착되고 있습니다. 규모의 경제로 가격도 많이 싸져서 운전자 지원 및 자율주행에 필수적으로 적용되는 센서 입니다.
- Radar 장점 : 날씨에 영향을 적게 받음, object까지 거리/각도/속력 측정 가능, object 단면 측정 가능하여 classify 가능(승용, 트럭, 사람, motorbike 등)
거리측정정확도(Resolution)는 Radar 동작 주파수와 무관하며 Bandwidth(f0+B)와 관계있다. Bandwidth가 클수록 거리 오차는 줄어듬. Receiver를 2개 이상 사용해서 object의 각도를 측정함, object의 속력은 도플러 효과에 의한 주파수 shift를 측정함으로써 얻어짐. object 단면은 signal power 측정값으로 계산함.(RCS[m²], Radar Cross Section)
77G+1G(high EIRP, LRR, MRR, Cuuise), 79G+4G(SRR, MRR, Perception)

위 그림에서처럼 10m 기준 감지 각도가 60도 이므로 바로 앞에서 cut-in 하는 차량을 감지하는데 한계가 있을 수 있습니다.
AutowareAuto 강좌에서는 ADE 환경을 통해 실행을 했는데, 일반 Ubuntu 환경에서도 동작합니다. (Ubuntu20.04 foxy에서 Test)
Radar 센서가 보급이 많이 되고 성능도 평준화가 많이 되어서 기본적인 object feature들은 CAN을 통해서 받아 볼 수 있습니다. 이 예제에서는 ARS408 센서로 부터 받은 CAN 메시지를 통해 감지된 Object feature들은 sorting한 뒤 ROS2 topic으로 publish하는 구조로 되어 있습니다.
canutils과 nettool을 설치 한다. $ sudo apt-get install -y can-utils
$ sudo apt install net-tools
코드 구조
├── CAN_Recording
│ └── candump.log // 콘티넨탈 레이더 CAN 데이터
├── radar_conti_ars408 // ROS2 node
│ └── src
│ ├── CMakeLists.txt
│ ├── include
│ | ├── ars_408_can_defines.h // raw value to physical
│ | ├── radar_conti_ars408_component.hpp
│ | └── visibility_control.h
│ ├── CMakeLists.txt
│ ├── launch
│ | └── radar.launch .py
│ ├── package.xml
│ └── src
│ ├── radar_conti_ars408_component.cpp
│ └── radar_conti_ars408_composition.cpp
├── radar_conti_ars408_msgs // 레이더 메시지 타입들
│ ├── CMakeLists.txt
│ ├── msg
│ │ ├── ClusterGeneral.msg
│ │ ├── ClusterList.msg
│ │ ├── Cluster.msg
│ │ ├── ClusterQuality.msg
│ │ ├── ClusterStatus.msg
│ │ ├── FilterCfg.msg
│ │ ├── FilterStateCfg.msg
│ │ ├── FilterStateHeader.msg
│ │ ├── ObjectExtended.msg
│ │ ├── ObjectGeneral.msg
│ │ ├── ObjectList.msg
│ │ ├── Object.msg
│ │ ├── ObjectQuality.msg
│ │ ├── ObjectStatus.msg
│ │ ├── RadarConfiguration.msg
│ │ ├── RadarState.msg
│ │ └── VersionID.msg
│ └── package.xml
└── ros2_socketcan_bridge // ROS2와 SocketCAN 브리지
├── can_msgs
│ ├── CMakeLists.txt
│ ├── msg
│ │ └── Frame.msg
│ └── package.xml
├── LICENSE
├── README.md
└── ros2socketcan_bridge
├── CMakeLists.txt
├── include
│ └── ros2socketcan.h
└── package.xml\
ROS2_SocketCAN_Bridge 원본은 https://github.com/ROS4SPACE/ros2can_bridge 참고
콘티넨탈ARS408레이더 안의 신호처리 블록에서 물체 감지(object detection), 클러스터링(clustering), object classification, tracking을 담당한다. 대부분 차량용 레이더 시스템들은 이러한 기능을 기본으로 제공하고 있다. 이렇게 감지된 object 데이터는 CAN으로 송출 된다. (차량의 In-Vehicle Network으로 연결되거나, 이 예제에서 처럼 Linux-CAN utils을 통해 PC에서 읽을 수 있음.)

이 예제에서는 레이더 센서로 부터 미리 받아온 CAN 데이터(CAN dump file)를 Virtual CAN 인터페이스를 통해 play하고 이를 Socket CAN 라이브러리로 읽는다. ROS2 node에서는 들어 오는 raw CAN 메시지를 읽어서 physical value로 바꿔서 우리가 필요한 object data로 publish한다. 이 object 메시지를RVIZ2에서 marker를 publish해서 표시한다.
- Radar 데이터 표시를 위한 ROS2 Lifecycle node 생성하기
1. ROS2 Lifecycle node 생성2. Publisher 와 CAN Subscriber, Callback 함수 생성, Virtual CAN을 통해 들어 오는 CAN 메시지를 구독(subscribe)하기 위해 먼저 SocketCAN object를 생성 한다. 그 다음 object message를 발행(publish)할 publisher를 생성한다.
2.1 CAN channel object 생성 (ros2socketcan canChannel0;)
2.2 Publisher 생성 (lifecycle publisher로 생성)
2.3 "can_receiver_callback" 생성(입력은 const can_msgs::msg::Frame)
2.4 "handle_object_list" 함수 생성
2.5 "publish_object_map" 함수 생성
2.6 object list를 위한 map container 생성(std library의 map사용, key는 object ID, value는 레이더object, radar_conti_ars408_msgs::msg)
2.7 레이더 object list "object_list_"를 위한 data structure 생성
2.8 추가 변수 구성3. ROS2 Publisher와 CAN subscriber 초기화
"object_list_publisher", "tf_publisher", "marker_array_publisher_"
can 채널 초기화 및 콜백과 bind4. Publisher 활성화(activate) (on_activate state)5. can receiver callback 생성 (Radar state message 대기, Radar state message의 Output Mode == 1이면, "handle_object_list"함수 호출)
GET_Radar... 함수, CALC_Radar... 함수 이용6. CAN메시지의 Status, General, Quality, Extended 값을 Object list로 변환한다. map data type을 이용한다. object ID는 map의 key에 대응 시키자.
- object handler 생성
6.1 CAN status message 수신 대기 (msg.id == ID_Obj_0_Status)
6.2 이전 object data를 publish (object_list_heaer, object_count, object_map), call publish_object_map(), rclcpp_lifecycle::LifecycleNode::now();
6.3 CAN message General, Quaility, Extended 값을 신규 object_map에 copy, msg.id==ID_Obj_1_General, msg.id==ID_Obj_2_Quality, msg.id==ID_Obj_3_Extended* radar object에 data들을 copy
ars_408_msgs::msg::Object o;
//object ID
int id = GET_Obj_1_General_Obj_ID(msg.data);
o.obj_id.data = GET_Obj_1_General_Obj_ID(msg.data);
//RCLCPP_INFO(this->get_logger(), "Object_ID: 0x%04x", //o.obj_id.data);
//longitudinal distance
o.object_general.obj_distlong.data = CALC_Obj_1_General_Obj_DistLong(GET_Obj_1_General_Obj_DistLong(msg.data), 1.0);7. RVIZ에 object를 표시하기 위해서 Marker(Cube as bounding box) 생성
- marker를 publish gksms 함수 생성
7.1 transform 생성
7.2 transform publish
7.3 marker array 생성 (visualization_msgs::msg::MarkerArray)
7.4 marker 생성
7.5 이전 marker 삭제 (marker.action=3, publish)
7.6 각 object에 대한 marker 생성8. Launch file 생성 (필요 패키지, 실행 파일들(CMakeList)과 노드 이름 설정)
실행 및 테스트
Host에서 virtual CAN 생성
$ sudo modprobe vcan
$ sudo ip link add dev can0 type vcan
$ sudo ip link set up can0
$ candump can0ADE 실행 후 CAN play (ade$ canplayer -I candump.log -l i)Radar 프로젝트 build (ade$ colcon build)Node launch(ade$ ros2 launch radar_conti_ars408 radar.launch.py)Rviz2 실행 (Host에서 실행)
add -> marker array (/ars408/marker_array)
add -> Axes (radar_link)
Global Options -> Fixed Frame = radar_link
ADE가 아닌 Ubuntu환경에서 실행은 아래 github 참고