introduction
CAN통신을 졸업연구 목적으로 경험하게 되어 이를 공유하고자 합니다. CAN통신은 h/w 셋업이 조금 번거로울 뿐 일단 한 번 준비가 되면 이더넷만큼이나 가벼우면서도 다른 문제와 씨름할 여지가 덜하다는게 큰 장점인듯합니다.
이 글에서는 차량의 CAN bus를 통해 전달되는 데이터를 수신 후 이를 의미있는 결과로 가공해내기 위해 ros에 연동하는것까지 진행해보도록 하겠습니다.
C-CAN, B-CAN, M-CAN
다른 곳에서도 잘 설명되어있겠지만, 차량 전장에서 통신할 정보가 많아지면서 can bus를 사용 목적에 따라 분리하기 시작했습니다. 차량 구동에 필요한 핵심 데이터(냉각수 온도, 흡기 유량, 구동토크, 등등...) 은 C-CAN(Chassis-CAN), 차량 구동에 큰 영향을 미치지 않는 전장에서 사용하는 데이터는 B-CAN(Body-CAN), 혹은 M-CAN으로 데이터를 송수신합니다.
테스트에 사용한 2016 Hyundai Avante AD 1.6 TCI-U2 차량은 C-CAN을 통해 차량 구동에 관련된 핵심 모듈 간의 통신을 수행하고 있었으며, M-CAN을 통해 그 외의 데이터를 송수신하는것을 확인할 수 있었습니다. 그 외에도 CAN-FD, FlexRay에 대한 부분도 확인할 수 있었으나, 주된 관심사는 아니기때문에 나중에 한 번 천천히 찾아보도록 하겠습니다.
차량간의 통신을 통해 어떤것들이 구현되고 있는가?
현대 GSW의 전장회로도를 보면 시스템들이 어떻게 구성되어있는지에 대한 감을 잡으실 수 있습니다. 그리고 조금 더 문서를 보다 보면 초기 차로이탈방지가 구현된 방식을 살펴볼 수 있습니다. 대시보드 유리에 있는 장착된 카메라 유닛과 AEB의 레이더만으로 차로이탈을 구현했다는 것인데... 이렇게 작은 사이즈의 카메라와 영상처리 보드로 차선을 인식하고, 차로이탈 방지에 필요한 조향각 등을 계산하여 C-CAN으로 뿌려주는식으로 동작했다는건데... 양산차에 탑재할만큼 안정적인 성능을 확보했다는 점에서 놀라움을 가져야 할지, 자율주행이라는 패러다임 앞에서 기존의 양산차 업계가 할 수 있는 선에서 해야할 것은 한 것 뿐인지는 좀 더 고민해봐야겠습니다. 기존 차량 시스템에서 새로운 장치를 add-on 식으로 추가할 수 있다는 것이 canbus가 가진 가장 큰 이점이 아닐까 싶습니다.
prerequisites + env
2016 Hyundai Avante AD 1.6 TCI-U2
raspberrypi 4B+ 4GB with MCP2515(Linux st 6.6.20, ubuntu 22.04 64bit)
ros2-humble
Peak Systems IPEH-004022 USB to CAN-FD
위의 h/w와 s/w를 기준으로 테스트를 진행하였으며, 여타 환경에서도 큰 차이는 없을 것으로 예상됩니다. 제 차량(...)을 테스트로 사용하였고, IPEH-004022 장비는 상당히 비싸니 시중에서 몇 천원으로 구입할 수 있는 MCP2515를 사용해도 무방합니다. 전용 s/w 지원 여부, 통신 안정성 등에서 차이가 발생합니다. 여기에서는 단순 값만 받아오는 것이기에 MCP2515만으로도 충분합니다. os는 글 작성 시점(2024-05-28) 기준 최신 이미지를 사용하였습니다. MCP2515를 라즈베리파이에 연결해 테스트하는 부분은 제가 쓴 이전 글을 참조하시기 바랍니다.
차량에서 어떻게 CAN 데이터를 뽑아내나?
⚠️ try at your own risk!
차량 can 데이터를 수신하는 것 자체는 큰 문제가 없을 것입니다. 그러나 이를 활용하여 차량에서 사용중인 message id로 데이터를 송신하는 등의 행위로 발생하는 모든 책임은 시도하는 분에게 있습니다. 특히 C-CAN은 엔진 가동상태에서만 사용할 수 있기에 개활지 주차, 고임목, 기어 N 등의 안전 조치를 최대한 한 다음 테스트하세요.
차량의 CAN bus는 와이어링 하네스를 통해 구성됩니다. 따라서 CAN이 있는 와이어링 하네스 선을 따서 구성하셔도 됩니다...만 그렇게 하지 않고도 OBD-II 커넥터에서 깔끔하게 CAN을 끌어올 수 있습니다. 현대 gsw에 방문하면 필요한 정보를 얻을 수 있습니다.
현대 gsw의 전장회로도를 보다보면 자기 진단 점검 회로 부분에 OBD-II 관련 내용이 있습니다. 이걸 참조하여 C-CAN 핀 부분에서 CAN 데이터를 얻어보겠습니다. 저는 DAG-3를 구입하면서 딸려온 OBD 커넥터의 해당 부분에서 CAN 라인을 따 왔습니다.
왼쪽 처럼 커넥터의 특정 핀에서 can 라인을 뽑아낸다음 이를 라즈베리파이에서도 읽어낼 수 있도록 했습니다. CAN 자체가 bus이기에 여기서 그냥 DAG를 그대로 써도 좋습니다.
Done!
comma.ai의 opendbc에 공유된 dbc를 바탕으로 ros2에 publish 해봤습니다. 모든 메시지를 해석하는 것은 그리 유익하지 않을듯하여 당장 확인하기 쉬운 부분만 체크해봤습니다. 안전벨트를 착용하니 /vehicle/CF_Gway_DrvSeatBeltSw 값이 1이 되는 것을 확인할 수 있습니다. SAS_Angle의 경우 값 범위가 -470~490 인걸 보니 deg 단위에 핸들 조향각 자체를 말하는듯 하여 바퀴 자체의 최대 조향각을 30도로 간주하여 rad로 표현하도록 했습니다.
사실 지금까지 can을 가지고 논건 차량에서 나오는 데이터로 차량의 kinematic model을 구성하여 위치에 대한 ekf를 돌리기 위함이었습니다. 따라서 여기서는 4 바퀴 각각의 휠스피드와 가속도값, yaw_rate, 조향각을 뽑는게 주 목적입니다.