온라인에서 장을 보거나, 필요한 물품을 구매하는 젊은 세대들과는 달리, 오프라인에서 물건을 직접 보고 고르며 장을 보는 것을 선호하는 어르신들 같은 분들은 거동이 불편하시거나, 카트를 끌 힘이 없는 분들이 있다. 그런 분들을 위한 마트에서의 쇼핑 전 과정에서 편리함을 주고 싶었다. 그래서 고객을 인식하면 뒤를 따라오며 고객이 카트를 끌 필요가 없고, 구매하고 싶은 물건의 위치를 안내해준다던지, 결제구역에 진입 시 자동으로 관리되고 있던 장바구니의 물건들을 자동결제 해주는 기능을 만들고 싶었다.
개인적으로 ROS2를 이용한 첫 번째 프로젝트로서 아직 ROS2를 잘(?) 사용한다고 할 수 없는 실력에서 프로젝트를 경험함으로써 많은 부분을 익히고 사용할 수 있게 되었다.
저번 프로젝트를 하며 느낀 부분이 속도, 설계인데, 첫 번째로 설계는 프로젝트를 시작함으로써 가장 먼저 시작하는 부분이지만 또 이 프로젝트를 성공적으로 마칠 수 있을지 없을지 가를 수 있는 과정이라는 것을 뼈저리게 느꼈다.
그래서 이번 프로젝트도 마찬가지로 기간은 3.5주이지만 수업을 하는 날이 더 많아, 프로젝트에 매진할 수 없는 시간이 많은 만큼 설계에 최대한 심혈을 기울이고 또 빠르게 끝내야 구현할 수 있는 시간이 늘어나니 효율적으로 설계하기 위해 강사님의 피드백을 적극적으로 이용했고, 또 수정했다.
또 하나의 부분은 속도인데 아무래도 이 부분은 PM의 역할이 굉장히 중요하다고 생각했다. 저번 프로젝트에서 PM의 역할은 맡지 않았다. 다른 팀원인 PM이 프로젝트 프로세스 스케줄링이나, 팀원 간 조율 및 소통보다 맡으신 구현 부분에 시간을 많이 투자하셔서(시간이 부족하기도 했다) 내가 대부분의 스케줄링, 팀원 간 조율을 맡아 했던 것 같다.
학부 시절 했던 프로젝트에서 나의 담당은 대부분 리더였지만, 지금 배우고 있는 과정에서는 경력자들이 많다 보니 내가 모르는 부분이 많을 것이라고 생각해 많이 양보했다. 경력자라고 해서 꼭 프로젝트 전체를 이끌어 갈 수 있는 것은 아닌 것 같다고 생각했다.
이번 프로젝트에서는 성공적으로 마무리했던 경험이 있는 팀원들과 함께 했다. 학원에서 정해준 팀이 아닌 자율로 팀을 만들었는데, 그중에서 존경(?)하는 팀원 중 한 명인 분이 PM을 맡게 되었다.
TMI지만 이 분도 경력자이시다. 그래서 부트캠프 초반에 우연히 옆자리에 앉게 되어, 많은 지식들을 알려주셨고, 실제로 나의 컴퓨팅 사고가 크게 향상할 수 있었고 너무 많은 도움이 되었다. 그리고 나와 결이 잘 맞다. 이 분과 이번 프로젝트까지 총 3개의 프로젝트를 했고 3개 다 좋은 결과가 있었다. (팀 프로젝트 1등 2번, Physical AI 해커톤 대회 최우수상)
이 분은 PM이 해야 하는 역할을 잘 알고 있었다. 발표도 맡으셨기 때문에 직접적인 구현보다 프로젝트의 큰 틀과 각 팀원들이 맡은 역할 및 진행사항 그리고 기술 스택 등 내가 생각했던 PM의 역할을 정말 잘 수행해주셨다.
그래서 이 프로젝트가 성공적으로 수행될 수 있었고, 또한 결과 또한 4팀 중 1등이라는 좋은 결과가 있었다. 또한 좋은 팀원들이 있었기 때문에 가능했던 결과이기도 하다. 한 명씩 소개하고 싶지만 글이 너무 길어질까 봐 여기까지 하겠다.
이제 기술적인 요소로 들어가 보자. 나도 항상 프로젝트에 임하면서 하는 부분은 좋은 습관인지, 안 좋은 습관인지는 모르겠지만 다른 팀원들이 하는 기술 구현, 진행사항을 항상 체크하려고 노력한다. 왜냐하면 나는 아직 무언갈 딥하게 공부하고 있다는 사람은 아니기 때문에 팀원이 열심히 공부하고 알아온 기술들을 설명을 들으며 나도 흡수하려고 하고, 언젠가는 또 쓰일 수 있다고 생각하기 때문이다. 그리고 다른 팀원의 진행사항을 알아야 나의 진행사항도 맞출 수 있기 때문이다. 내가 빠르다면 좀 더 덜 우선순위인 작업들도 함께 병행한다. 느리다면 더욱 구현에 집중한다.
부트캠프에서 자율주행에 대한 것을 배우면서 기본적인 지식을 얻었지만 프로젝트에서 기본적인 지식만으로는 부족한 부분이 있었다. 그래서 팀이 정해진 후 곧바로 스터디를 시작했다.
매일매일 각자가 조사할 기술을 선택한 후, 다음 날 미팅까지 조사하고 공부하여,
이런 식으로 각 카테고리에 대한 부분을 한 줄로 설명하고 그밖에 팀원들이 이해할 수 있도록 최대한 자세히, 그리고 쉽게 발표하고 또 필요할 때마다 볼 수 있도록 Confluence에 문서로 관리하였다.
이 스터디는 실제로 많은 도움이 되었다. 특히 개인적으로 주행에 대한 기술 구현을 담당했기 때문에, 우리가 스터디했던 주제들이 자율주행과 관련된 부분이었기 때문에 무언가 궁금하거나 서칭을 해야 할 경우 많이 참고하기도 했고, 선행적인 기술조사로 실제 구현 시 이해되는 부분이 많았다.
우리는 주제가 정해지고, 곧바로 맵 디자인에 들어갔다. 맵은 Pinky가 여러 경로로 이동하고, 한 복도에서 Pinky 2대가 지나갈 수 있는 넓이로 복도를 만들고, 최대한 실제 마트와 비슷한 환경으로 만들기 위해 노력했다. 다만 일반적인 마트에서, 사용자를 추종하는 로봇이 추가되기 때문에 동선에 대한 고민을 많이 했다.
기계공학과인 나는 학부 시절 배웠던 캐드와 3D 모델링으로 맵 디자인을 문서화하여 토대로 가제보 world를 세팅할 수 있게 하고, 맵에 필요한 구조물을 3D 프린팅 설계하였다.
맵 세팅을 다 한 후, 기능 구현을 위한 기술조사에 들어갔다. 실습시간에는 로봇 한 대만 자율주행을 해봤기 때문에 하나의 서버에서 여러 대의 로봇을 효율적으로 관제할 수 있는 기능이 필요했다.
여기서 효율적이라는 말은 만약 로봇이 당근이라는 채소코너로 고객을 안내를 해줄 경우에 맵핑되어 있는 위치로 이동하는데, 2대 혹은 여러 대의 로봇이 동시에 채소코너로 이동하거나, 아니면 채소코너에 이미 여러 대의 로봇이 있을 경우 로봇 간의 경로 병목 및 충돌 가능성이 있다. 이러한 부분을 해결하기 위해 오픈소스 미들웨어인 Open-RMF라는 것을 채택했다.
우리는 로봇이 2대이기 때문에 2대만 운용한다는 것을 고려하여 각 코너마다 노드를 2개씩 두었다.
가장 힘들었던 부분은 Nav2 파라미터 튜닝이었다. 1.4 × 1.8m라는 극도로 좁은 공간에서 로봇이 선반에 부딪히지 않으면서도 통로를 통과할 수 있도록 inflation_radius를 0.1 → 0.05 → 0.025 → 0.01까지 수십 번 조정했다. costmap의 cost_scaling_factor도 150에서 5까지 줄여가며 최적값을 찾았다. 시뮬레이션에서 잘 되던 값이 실제 Pi 5에서는 연산 부하 때문에 경로 계획이 늦어지는 문제도 있어서, planner 주기를 낮추고 BT server timeout을 500ms까지 늘려야 했다.
ROS 2 Jazzy 호환성 문제도 난관이었다. collision_monitor의 파라미터 형식이 이전 버전과 달라서, empty string_array 설정부터 minimal stop polygon 설정까지 7~8번의 커밋을 거쳐야 했다. docking_server config도 Jazzy에서 필수로 요구되어 추가해야 했다.
Gazebo 시뮬레이션에서 완벽하게 동작하던 것이 실제 로봇에서는 안 되는 경우가 많았다.
- FastDDS 멀티캐스트 문제 — 시뮬레이션에서는 localhost라 문제없었지만, Wi-Fi 환경의 실제 로봇에서는 DDS discovery가 불안정했다. 유니캐스트로 전환을 시도했지만 시뮬레이션이 깨져서 결국 revert했다.
- AMCL 초기 위치 — Gazebo world 좌표와 map frame 좌표가 달라서 실제 로봇의 초기 위치가 엉뚱한 곳에 잡히는 문제가 있었다. map frame 기준으로 좌표를 재계산해야 했다.
- namespace 격리 — 멀티로봇 시뮬레이션에서 각 로봇의 토픽이 충돌하지 않도록 namespace를 분리했는데, 실제 로봇에서는 하드웨어 서비스 클라이언트에도 namespace를 적용해야 해서 추가 작업이 필요했다.
여러 대의 로봇이 동시에 같은 코너로 이동하거나, 이미 로봇이 있는 곳으로 향할 경우 경로 병목 및 충돌 가능성이 있었다. 이를 해결하기 위해 오픈소스 미들웨어인 Open-RMF를 채택하고 Fleet Adapter를 직접 구현했다. 28개 노드의 Nav Graph를 설계하고, 로봇 2대를 고려하여 각 코너마다 노드를 2개씩 배치했다.
하지만 프로젝트 후반부에 RMF의 복잡도와 우리 환경에서의 제약으로 인해 PM이 자체 Fleet Router로 전환하는 결정을 내렸다. 충돌 감지(E_SHARE, E_OPPOSE, V_CONVERGE)와 양보 우선순위 로직을 직접 구현하여 더 우리 환경에 맞는 솔루션을 완성했다.
- ROS2 경험 — 토픽/서비스/액션의 개념을 넘어서, namespace 격리, lifecycle 관리, DDS 설정 등 실무적인 ROS2 운용 능력을 얻었다.
- Nav2 깊은 이해 — costmap, planner, controller, behavior tree의 관계를 파라미터 튜닝을 통해 체득했다.
- 시뮬레이션과 실제의 간극 — "시뮬레이션에서 되니까 됐다"가 아니라, 실제 환경에서의 검증이 얼마나 중요한지 배웠다.
- 설계 문서의 가치 — 18개 시나리오, 인터페이스 명세, 상태머신 문서가 구현 단계에서 팀원 간 "이거 어떻게 되는 거야?" 질문을 크게 줄여주었다.
- PM과 팀워크 — 좋은 PM이 있으면 팀원들이 자기 구현에 집중할 수 있다는 것, 그리고 팀원의 진행사항을 파악하는 것이 자신의 속도 조절에도 중요하다는 것을 다시 한번 확인했다.
이 모든 과정을 거쳐 프로젝트를 성공적으로 마무리했고, 4팀 중 1등이라는 좋은 결과를 얻었다. 좋은 팀원들이 있었기에 가능했던 결과이다.