채용공고 올리기

조영훈님을 응원해보세요!

지금 만족하고 있어요
성실함
책임감
솔루션 지향
목표 지향적
커뮤니케이션

미리보기

기본 정보

이름
조영훈
직업
로봇 제어 엔지니어
간단 소개

주어진 비지니스 요구사항을 해결하기 위해 노력하는 로봇제어 개발자입니다.

기술 스택

기술 스택

C++, C#, wpf, winform, Python, robotics

경력

회사명

(주)티로보틱스

직급 | 부서 | 근무 유형

책임 | 개발2팀 | 재직 중

근무 기간

2021.11. ~ 재직 중 (3년)

담당 업무

OTIS AGV 제어용 ACS 개발

  • AGV 목적지 설정 및 경로 설정

  • 아키텍쳐 설계

  • Device 모듈 개발

LGIT C4 Conveyor Type AMR 개발

  • ACS 통신 I/F 모듈 설계 및 개발

  • AMR Main Logic 개발

  • Log System 설계 및 개발

  • Alarm System 설계 및 개발

  • Sensor Data Integration

  • AMR 공통 모듈 개발

  • GUI 통신 모듈 개발

LGIT C1 C1 Lift Type AMR 개발

  • ACS 통신 I/F 모듈 설계 및 개발

  • AMR Main Logic 개발

  • IO, PIO 모듈 설계 및 개발

  • Lift Up, Down 로직 개발

  • Log System 설계 및 개발

  • Alarm System 설계 및 개발

  • Sensor Data Integration

  • AMR 공통 모듈 개발

LGIT C7 Cobot Type AMR 개발

  • AMR Main Logic 개발

  • IO, PIO 모듈 설계 및 개발

  • Log System 설계 및 개발

  • Alarm System 설계 및 개발

  • Sensor Data Integration

  • AMR 공통 모듈 개발

LGIT C4, C5 Lift Type AMR 개발 (진행중)

  • ACS 통신 I/F 모듈 설계 및 개발

  • IO, PIO 모듈 설계 및 개발

  • Log System 설계 및 개발

  • Alarm System 설계 및 개발

  • Sensor Data Integration

  • AMR 공통 모듈 개발

회사명

앤로

직급 | 부서 | 근무 유형

선임 | 개발팀

근무 기간

2019.08. ~ 2021.11. (2년 4개월)

담당 업무

봇봇봇 대전 신세계점 Drink 및 Drip Bot 아키텍처 설계 및 개발

  • 드링크, 드립 Control Template 적용

  • SW 아키텍쳐 설계

  • Service 모듈 개발

  • Common 모듈 개발

  • Device 모듈 개발

ICTK VISA 검증 장비 개발

  • Test Position 변경 및 Position ID 추가

  • 단말기 테스트 시 Card Fail Code 변경 및 Error 상황 시 동작 변경

  • Test Result 포맷 변경

  • Middleware 변경으로 인한 동작 시퀀스 변경

서빙로봇 Avoidance 용 카메라 모듈 개발

  • 카메라 뎁스 데이터 변환

봇봇봇 성수 점 리뉴얼 및 유지보수

  • 드립 봇 기능 개선

  • 디저트 봇 기능 개선

  • UI 인터페이스 개선 ( 공통 )

회사명

(주)티로보틱스

직급 | 부서 | 근무 유형

사원 | 로봇자동화사업부

근무 기간

2018.01. ~ 2019.07. (1년 7개월)

담당 업무

성수 봇봇봇 UI, 로봇 제어용 로직개발 및 윈도우 응용프로그램 개발

  • 주문 관리 파트 개발

  • Serial 장비 통신 모듈 개발

  • 컨텐츠 Application 모듈과의 통신모듈 개발

  • 서버, 클라이언트 통신모듈 개발

  • 로봇 통신 모듈 개발

  • 재료 및 레시피 관리 모듈 개발

  • 에러 상황 시 리포팅 및 Log 분석기 개발

  • 원격 업데이트 및 다운 그레이드 모듈 개발

AGV Debugging 및 Scenario Test 용 Mater Program 개발

  • AGV 시나리오 관리 모듈

  • AGV Navigation 모듈

Wafer 이송 및 Align 장비 EFEM Revision

  • Universal Robot 시퀀스 변경 및 티칭

  • Alignment 모듈 통합

  • Wafer 추적기능 추가

프로젝트

프로젝트명

LGIT C4, C5 Lift Type AMR 개발

소속/기관명

티로보틱스

프로젝트 기간

2024.06. ~ 진행 중

프로젝트 내용

개요

LG이노텍에 납품했던 Lift 타입의 AMR 개발 및 셋업 프로젝트였다.

ACS는 LG CNS, AMR은 자사가 납품하였다.

SLAM 후 미리 ACS에서 지정해놓은 Node ( Point ), 및 Link ( Node - Node ) 로 주행하는 타입의 AMR이다.

세부 내용

  • 기간 : 2024.06 ~ ing

  • 개발 언어 : C++, Python

  • 발 환경 및 사용 라이브러리

    • ROS2 Galactic

    • Intel Realsense Camera SDK

    • Opencv

    • Boost::Asio

담당 파트

프로젝트 일정 관리 및 팀 리딩

  • HW 팀과의 DR 및 일정 조율

  • Setup 일정 계획 및 조율

  • 프로젝트 SW 이슈 관리

  • 개발 일정 관리 및 인력 관리

ACS 통신 I/F 모듈 설계 및 개발

  • ACS 통신을 위한 메세지 패킷 데이터 모델 설계 및 구현

  • ACS Command Validation 모델 설계 및 구현

  • 비동기 서버 구현 ( 1:1 통신 )

IO, PIO 모듈 설계 및 개발

  • MODBUS TCP 통신 모듈 개발

  • IO Address 맵핑

  • Charge, Charge Stop PIO Logic 개발

  • PIO Stop, Reset 로직 개발

Log System 설계 및 개발

  • 상황별 Log 분리 ( LOG_INFO, LOG_ERR, LOG_WARNING )

  • 각 패키지 별 공통 logger 설계 및 구현

  • 3개월 이상 된 Log 삭제 Logic 구현

Alarm System 설계 및 개발

  • 각 알람 별 Layer 화 ( Layer 1 : 센서류 알람, Layer 2 : 제어기 알람, Layer 3 : 메인 알람 )

  • Alarm Reset Logic 개발

  • Alarm 상태 세분화 ( ALARM_NONE, ALARM_OCCUR, ALARM_WARNING, ALARM_IGNORE )

AMR 공통 모듈 개발

  • Alarm Auto Clear 및 Auto Reporting 을 위한 AlarmBaseNode 설계 및 구현

  • 각 Node 상태 Reporting을 위한 BaseNode 설계 및 구현

  • Logger, Converter 설계 및 구현

  • 각 패키지 별 공통 Data Type 분리 및 구현 ( ACS, AMR, 각 Device 등등 )

어려웠던 점

개발팀 리빌딩

프로젝트 투입 후 가장 먼저 했던 일은 팀을 재정비 하는 것이었다. 팀장은 아니였지만 사실상 팀장 역할을 해야 했던 상황이라 팀 리빌딩부터 진행하였다. 팀 리딩 경험이 없었기 때문에 처음엔 어떤 걸 해야할지 몰랐었다.

먼저 팀원들과 함께 팀 또는 각자가 해결해야 할 솔루션 유지보수, 고객사 납품라인 현장 대응, C4/C5 Lift AMR 개발 대응 등 당면한 이슈들을 리스트 업을 진행하였다. 그 후 각 업무에 대한 우선순위를 정하고 개발팀이 신규 장비 납품을 위해 개발에만 집중할 수 있도록 영업팀 및 CS팀과 협의 후 현장 대응 인원들에게 SW 패치 업무는 인계하였다.

팀 내에서 해야할 업무가 정리되고 나서 가장 먼저 한 일은 팀원들이 프로젝트의 어느 파트를 담당할 것인지 정하는 일이었다. 각 파트 담당이 정해진 후 개발 프로세스 관리를 위해 매주 월요일 오전은 코드리뷰 후 코드 Merge 하기, 각 주의 끝내야 할 업무 정리하기 등 한 주의 개인 업무 파악을 진행하였다. 또한 각 파트 담당들의 업무가 밀리는 경우, 막히는 경우에는 같이 리뷰하고 고민하며 서포트하였다. 처음에는 다들 어색해하고 어려워했지만 한 주, 한 주가 지날 수록 정기적인 리뷰를 제외하더라도 각 파트 담당들끼리 협업이 잘되며 효율이 나오기 시작하였다.

리딩업무가 처음이였기 때문에 잘 하고 있는 것인지, 현재 프로젝트 개발 일정과 팀 내 역량이 나오는지 초기에는 가늠이 잘 서지 않았지만 팀원들의 많은 도움과 업무 프로세스를 조금씩 다듬어 가며 잘 완수할 수 있었다.

유지 보수가 쉬운 코드 만들기

프로젝트 투입 후, 매 번 새 프로젝트를 시작할 때 마다 새로 만들어야 하는 파트들에 대해 많은 고민을 했었다. 특히 Alarm, Log 시스템 같은 경우 각 프로젝트마다 명확하게 정해진 포맷이 없어 프로젝트 별로 로그 분석기를 만들어야 했으며 최종 결과물이 재사용 불가능 한 경우가 많았다. 또한 각자 시간에 쫓겨 개발하다 보니 각 파트를 개발한 사람이 아니면 유지보수가 거의 불가능에 가까웠다.

이를 해결하기 위해 매주 월요일 오전 모든 팀원들과 함께 각자 파트에 대한 코드 리뷰를 진행하였고, 필요한 경우 각 파트 담당자들만 따로 불러 리뷰 후 각 모듈간 통신을 위한 인터페이스 정의, 각자의 파트가 어떻게 동작하는지 등 서로의 코드를 더 잘 이해할 수 있도록 개인 리뷰시간도 가졌다.

정리

개발 일정 관리 및 팀 리딩을 하다 보니 밸런스가 정말 중요하다는 걸 느꼈다. 각 팀원들간의 도메인, 기술적인 격차를 줄이기 위해 도입했던 정기적인 코드리뷰, 모두가 한 방향으로 갈 수 있게 투명하게 오픈했던 모든 정보들, 코드 컨벤션 및 개발 프로세스 정립을 위해 프로젝트 초반 많은 시간을 할애했고 팀원들이 모두 동의했던 개발 프로세스 등 이번 프로젝트를 하면서 새로운 개발 문화를 만들고 도입하면서 많이 배우게 되었던 프로젝트 였던 것 같다.

다만 프로젝트 일정 상 개발일정이 너무 급하여 최소한의 개발 프로세스만 갖추게 되었지만 차후 팀원들과 가독성 좋은 코드, 솔루션 내에서 각 모듈간의 R&R, 낮은 결합도와 높은 응집도를 만들기 위한 방법 등등 여러 가지를 같이 고민하며 성장하는 팀을 만들고 싶다는 생각이 들었다.

프로젝트명

LGIT C7 Cobot Type AMR 개발

소속/기관명

티로보틱스

프로젝트 기간

2023.12. ~ 2024.07.

프로젝트 내용

개요

LG이노텍에 납품했던 Manipulator가 장착된 타입의 AMR 개발 및 셋업 프로젝트였다.

ACS는 LG PRI, AMR은 자사가 납품하였다.

카메라 렌즈가 담겨있는 Tray를 AMR이 이적재 및 이송하는 컨셉의 AMR 개발 프로젝트이다.

SLAM 후 미리 ACS에서 지정해놓은 Node ( Point ), 및 Link ( Node - Node ) 로 주행하는 타입의 AMR이다.

세부 내용

  • 기간 : 2023.12 ~ 2024.07

  • 개발 언어 : C++, Python

  • 발 환경 및 사용 라이브러리

    • ROS2 Galactic

    • Intel Realsense Camera SDK

    • Opencv

    • Boost::Asio

담당 파트

프로젝트 일정 관리 및 팀 리딩

  • HW 팀과의 DR 및 일정 조율

  • Setup 일정 계획 및 조율

  • 프로젝트 SW 이슈 관리

  • 개발 일정 관리 및 인력 관리

AMR Main Logic 개발

  • 주행 방법 및 주행 방향 변경에 따른 Ambient Light ( 주행방향 표시등 ) Logic 개발

  • 상황별 ( 대기, 주행, Task 수행, Docking, Undocking, Alarm 등등 ) Sound 및 Light 제어 Logic 개발

  • Transfer 수행 시 Docking, PIO, Undocking Logic 개발

  • AMR Pause, Resume, Stop 기능 개발

  • Safety Lidar 안전영역 세팅 및 변경 Logic 개발

  • AMR Status 보고용 Data Model 설계 및 구현

IO, PIO 모듈 설계 및 개발

  • MODBUS TCP 통신 모듈 개발

  • 상황 별(Charge, Charge Stop, Acquire, Deposit) PIO Logic 개발

  • PIO Stop, Reset 로직 개발

Log System 설계 및 개발

  • 상황별 Log 분리 ( LOG_INFO, LOG_ERR, LOG_WARNING )

  • 각 패키지 별 공통 logger 설계 및 구현

  • 3개월 이상 된 Log 삭제 Logic 구현

Alarm System 설계 및 개발

  • 각 알람 별 Layer 화 ( Layer 1 : 센서류 알람, Layer 2 : 제어기 알람, Layer 3 : 메인 알람 )

  • 각 패키지 별 공통 Alarm Sub, Alarm Pub 구현

  • Alarm Reset Logic 개발

AMR 공통 모듈 개발

  • Solution 내 패키지들에서 재사용 가능한 공통 모듈 설계

  • Logger, Data type structure 설계 및 구현

  • 비동기 서버, 클라이언트 설계 및 구현

  • 각종 Converter 및 File IO 클래스 설계 및 구현

어려웠던 점

프로젝트 일정 관리

23.12월 까지 LGIT C4 Conveyor Type AMR 개발 프로젝트로 인해 장기 출장 후 본사 복귀하자마자 프로젝트 내에서의 개발 관리 업무를 맡게 되었다. SW개발은 Manipulator 제어를 위한 개발 1팀, Manipulator를 제외한 주행부, Docking, Undocking, PIO, Alarm, ACS 등 파트로 구성되어있는 개발 2팀으로 구성되어있었다.

내가 맡은 개발 파트 이외에도 개발 2팀 Task의 개발 관리 업무 및 HW팀과의 DR, 일정 조율까지 담당하게 되었다. 일정 상 24년 1월 초 가공품 발주, 24년 2월 초 HW 조립 완료, 24년 2월 중순 FAT 및 고객사 납품까지 이루어져야 하는 빡빡한 일정이었다.

HW 가공품 발주 전주 디자인 리뷰에서 여러 하드웨어 결함들을 발견하였고 해당 가공품 설계 수정 및 부품 구매를 위해 급하게 HW팀 및 고객사와 일정 조율이 필요하였다. AMR 충전 시 후면도킹으로 진행하였고 도킹을 위한 Marker Detect이 필요했는데 AMR 후면부에 카메라가 빠져있었다. 또한 Manipulator Gripper, Sensor 들, Motor Driver ( RS485 통신 ) 을 위해 Serial Port or USB Port 가 많이 필요했는데 제어용 PC에는 포트가 두 개 밖에 없었다. 해당 문제를 해결하기 위해 급히 카메라 추가 발주 및 브라켓 추가 설치, Serial 통신 용 USB 허브를 구매하였다.

결국 HW 조립일정 및 SW 테스트 일정이 밀렸지만 고객사 납품일은 미룰 수 없어 밤을 새워 프로젝트를 진행해야 하는 상황이었다.

또한 개발 1팀과의 커뮤니케이션이 원활하게 되지 않아 개발 1,2팀의 진행상황 공유도 되지 않았고 결국 고객사 납품 후 큰 리스크로 돌아오게 되었다.

사내 팀 끼리의 협업

이번 프로젝트는 개발 1팀, 개발 2팀으로 나누어 진행하였다. 개발 1팀은 Manipulator 제어, 설비 측 서랍을 열기위한 Drawer 팀으로 구성되어 있었으며 개발 2팀은 주행부, ACS 통신부, IO/PIO 등 디바이스 제어 팀으로 나누어져 있었다. 프로젝트 투입 후 상세 SW 설계에 시간을 투자하지 못하며 HW이슈 대응을 위해 설계 DR을 중점적으로 참여하다 보니 개발 1팀과의 개발 싱크가 맞지 않게 되었다. 주행부는 개발 완료되었지만 task 수행을 위한 인터페이스가 정의되지 않았다던지, IO, 카메라 등 디바이스 모듈은 개발완료되었지만 해당 모듈을 사용하는 handler 파트가 개발되지 않았다던지 하는 여러 이슈들이 겹쳐서 발생하였다. 해당 이슈를 해결하기 위해 매주 코드리뷰 및 MR 진행하자고 제안하였지만 개발 속도를 늦춘다는 이유로 기각되었었다.

결국 고객사 납품 전 FAT에서 SW관련 Integration, 각 모듈 간 Interface 부재, alarm 처리 미흡, log 미흡 등 큰 이슈가 발생하게 되었고 이는 고스란히 프로젝트의 큰 Risk로 남게 되었다.

정리

프로젝트를 진행하며 처음으로 개발실무와 개발관리를 맞게 된 프로젝트였다. 당시 개발 1팀 에는 리더분이 있었지만 개발 2팀에는 리더 직책의 인원도 없었고 각자 따로 파트를 맡아 개발하는 형식이었다. 개발이 제대로 진행될 것 같지 않아 팀원들을 모아놓고 명확한 파트 재분배, 주행부와 센서부 데이터 송수신 인터페이스 재정의, 주행 후 Task 수행까지의 로직, 알람 코드 등을 재정의 하며 프로젝트 리딩 및 납품 준비를 하였었다.

납품 후 예상대로 많은 Issue List들이 나왔으며 대부분은 SW에 관한 내용들이었다. 개발 단계에서부터 Risk 관리 없이 기능만 우선 구현하자 라는 마인드로 진행했던 프로젝트 중에서 가장 많은 이슈가 있었던 프로젝트였으며 결과론적으로는 다 해결이 되었지만 자칫 잘못했으면 회사에 큰 손실을 끼칠뻔 하기도 했던 프로젝트였다.

이번 프로젝트를 진행하며 주기적인 코드리뷰, MR/PR 시 각자의 코드 공유 및 리뷰의 중요성을 깨닫게 되었고 설계, 전장 팀들 뿐만이아니라 셋업팀과의 협업에 대해 다시 한 번 고민하게 되었다.

또한 같은 개발팀 간의 협업, 팀 내부에서의 파트 분배 및 인력관리 등에 대해 좀 더 깊이 고민하게 되었으며 다음 프로젝트부터는 어떻게 프로젝트 관리를 해야 할까 고민이 많이 되었던 프로젝트였다.

프로젝트명

LGIT C1 C1 Lift Type AMR 개발

소속/기관명

티로보틱스

프로젝트 기간

2023.05. ~ 2023.11.

프로젝트 내용

개요

LG이노텍에 납품했던 Lift 타입의 AMR 개발 및 셋업 프로젝트였다.

ACS는 LG PRI, AMR은 자사가 납품하였다.

매거진이 실려있는 대차를 AMR이 이적재 및 층간 이송하는 컨셉의 AMR 개발 프로젝트이다.

SLAM 후 미리 ACS에서 지정해놓은 Node ( Point ), 및 Link ( Node - Node ) 로 주행하는 타입의 AMR이다.

세부 내용

  • 기간 : 2023.05 ~ 2023.11

  • 개발 언어 : C++, Python

  • 발 환경 및 사용 라이브러리

    • ROS2 Galactic

    • Intel Realsense Camera SDK

    • Opencv

    • Boost::Asio

담당 파트

ACS 통신모듈 개발

  • 비동기 TCP 서버 개발 ( 1:1 통신 )

  • ACS 메세지 프로토콜 파싱 및 ACS Data Type <-> AMR Data Type 컨버터 개발

  • 중복명령 Block Logic 개발

  • AMR Status 보고용 Data Model 설계 및 구현

주행 및 Transfer 수행 Logic 개발

  • 에어샤워, E/V 사람과 동시 탑승 방지를 위한 주행 중 A/S Block 및 E/V Block 로직 개발

  • 주행 경로 파싱 후 AMR Turn 및 에어샤워 Open 대기 Logic 개발

  • 상황별 ( 대기, 주행, Task 수행, Docking, Undocking, Alarm 등등 ) Sound 및 Light 제어 Logic 개발

  • Transfer 수행 시 Docking, PIO, Undocking, Lift 제어 Logic 개발

  • AMR Pause, Resume, Stop 기능 개발

  • E/V 탑승 후 Map Change 및 Localization 로직 개발

  • 과충전 방지를 위한 Lower, Upper SOC Limit 도달 후 Auto Charge Stop Logic 개발

Alarm Manage 모듈 개발

  • Package 별 Alarm 취합 및 중, 경알람 처리 Logic 개발

  • Alarm 발생 시 AMR Stop 및 ACS로 Report 모듈 개발

  • Alarm Reset Logic 개발

GUI 통신 모듈 개발

  • GUI <-> AMR 통신 인터페이스 설계 및 구현

  • AMR Jog 동작 및 PIO, Docking, Undocking 인퍼페이스 설계 및 구현

  • AMR Confidence ( 맵핑률 ) 저하 시 Relocation 기능 개발

어려웠던 점

AirShower / Elevator Block Logic 개발

AMR이 사람과 동시에 탈 수 없을 정도로 엘레베이터, 에어샤워가 협소했기 때문에 사람이 안에 있다면 AMR은 사람이 빠져나올 수 있을 정도의 거리를 두고 대기, 사람이 안에 없다면 미리 에어샤워 오픈 및 엘레베이터 오픈 후 사람이 탈 수 없게 Block 하는 Logic개발이 가장 어려웠었다. 에어샤워, 엘레베이터 제어는 PLC 모듈을 만들어 IO로만 제어하게 되어 있었는데 에어샤워 센서는 IO로 받는게 불가능하였고 엘레베이터 내부는 센서가 존재하지 않았다. 또한 승강기 법령 상 엘레베이터 내부에 센서를 임의로 설치할 수도 없었기 때문에 다양한 케이스 별로 AMR 자체에서 인터락을 걸어야 했다.

초기에는 사람과 AMR이 에어샤워, 엘레베이터에서 마주보는 경우가 종종 있었고 해당 상황에서는 AMR을 수동으로 에어샤워 바깥까지 빼낸 후 리셋, Relocation을 진행한 후에야 다시 동작할 수 있었지만 엘레베이터 문 열림, 에어샤워 문열림 IO 감지 전까지 AMR은 특정 위치에서 대기시켜놓고 해당 Input 을 받은 후에야 동작하게 개선하였다.

짧은 개발기간

하기 LGIT C4 Conveyor Type AMR 개발 프로젝트 도중 Lift AMR 하드웨어가 완성되었다고 고객사 라인에 선 납품 후 고객사 라인에서부터 개발을 시작하였다. 장비에 대한 컨셉, 라인 환경, 요구사항 등 어떠한 문서도 없이 고객사 라인안에서 현장 상황에 맞게 처음부터 짧은시간 안에 개발을 완료해야 했던 프로젝트 였기 때문에 솔루션 구조, 각 패키지별 R&R에 대한 고민 없이 일단 기능부터 만들고 AMR이 주행 가능하게 하자는 마인드로 개발을 진행하였다.

정리

개발 기간이 촉박했을 뿐만 아니라 개발과 셋업을 동시에 진행해야 하는 상황이었다. 또한 이미 진행하고 있던 프로젝트와 동시에 병행해야 했던 만큼 정말 힘들게 개발을 진행했었다.

22년 5월에 개발을 시작하여 6월 중순에 개발 완료 및 모니터링 까지 완료하였지만 잦은 하드웨어 이슈 ( 전장 케이블 단선 및 전원 계통부 OverVoltage )가 있었으며 결국 프로젝트 완료는 5개월 뒤인 11월에 완료되었다.

이번 프로젝트를 진행하면서 개발자의 역할에 대해 다시 한 번 생각해보게 되었다. 솔루션 구조, 얼마나 효율적으로 짠 코드인지, 가독성이 좋고, 응집력이 높고 결합도가 낮은 코드에 대해서만 생각하고 있었지만 비지니스 관점에서 다시 생각해보니 어려운 환경에서도 비지니스 요구사항을 충족할 수 있게 빠르고 안정적인 코드를 짜는 것도 중요하다는 것을 배웠다.

또한 주어진 환경에서 할 수 없는 것을 할 수 있게 만들기 위해 스스로 어떤 부분을 채워야 할 지, 어떤 마인드셋을 가져야 할 지 다시 한 번 돌아보게 되었다.

프로젝트명

LGIT C4 Conveyor Type AMR 개발

소속/기관명

티로보틱스

프로젝트 기간

2022.12. ~ 2023.12.

프로젝트 내용

개요

LG이노텍에 납품했던 컨베이어 타입의 AMR 개발 및 셋업 프로젝트였다.

ACS는 LG CNS, AMR은 LG PRI 및 자사가 같이 납품하였다.

BOX 타입의 적재물을 스토커 및 각 설비로 AMR이 이적재 및 이송하는 컨셉의 AMR 개발 프로젝트이다.

SLAM 후 미리 ACS에서 지정해놓은 Node ( Point ), 및 Link ( Node - Node ) 로 주행하는 타입의 AMR이다.

세부 내용

  • 기간 : 2022.12 ~ 2023.12

  • 개발 언어 : C++, Python

  • 발 환경 및 사용 라이브러리

    • ROS2 Galactic

    • Intel Realsense Camera SDK

    • Opencv

    • Boost::Asio

담당 파트

ACS 통신모듈 개발

  • 비동기 TCP 서버 개발 ( 1:1 통신 )

  • ACS 메세지 프로토콜 파싱 및 ACS Data Type <-> AMR Data Type 컨버터 개발

  • 중복명령 Block Logic 개발

  • AMR Status 보고용 Data Model 설계 및 구현

주행 및 Transfer 수행 Logic 개발

  • 주행 Node 에 따른 주행 방향 ( Forward, BackWard ) 계산 Logic 개발

  • 주행 방법 및 주행 방향 변경에 따른 Ambient Light ( 주행방향 표시등 ) Logic 개발

  • 상황별 ( 대기, 주행, Task 수행, Docking, Undocking, Alarm 등등 ) Sound 및 Light 제어 Logic 개발

  • Transfer 수행 시 Docking, PIO, Undocking, Conveyor 제어 Logic 개발

  • AMR Pause, Resume, Stop 기능 개발

Alarm Manage 모듈 개발

  • Package 별 Alarm 취합 및 중, 경알람 처리 Logic 개발

  • Alarm 발생 시 AMR Stop 및 ACS로 Report 모듈 개발

  • Alarm Reset Logic 개발

GUI 통신 모듈 개발

  • GUI <-> AMR 통신 인터페이스 설계 및 구현

  • AMR Jog 동작 및 PIO, Docking, Undocking 인퍼페이스 설계 및 구현

  • AMR Confidence ( 맵핑률 ) 저하 시 Relocation 기능 개발

어려웠던 점

Map Synchronization

하나의 ACS에 두 업체의 AMR이 사용되다 보니 맵 동기화가 가장 난관이였다. LG PRI와 자사 모두 각 사 제품들에는 하나의 맵을 AMR이 공유하면서 사용가능했지만 PRI와 자사 제품 간에는 맵 공유가 불가능했다. 고객사 라인의 맵 크기가 컸었기 때문에 SLAM을 시작한 원점에서 부터 멀어질 수록 맵 오차율이 심해졌고 ACS에서 제공한 Node의 좌표로는 두 업체간 동기화가 불가능하였다.

결국 현장상황에 맞게 자사 자체적인 Map 좌표대로 AMR을 구동시켰으며 ACS에 보고할 때에만 Node 이름을 매칭시켜 x,y 좌표를 ACS에 맞게 변환하여 보고하였다.

Map 자동 Update

셋업시 ACS의 맵이 변경되었을 때 자동으로 Map Update를 해달라는 요구사항을 전달받았다. 해당 기능 구현을 위해 ACS 맵 포맷은 엑셀 파일을 파싱하여 자사 맵 포맷으로 변환하는 작업이 필요하였다.

ACS 맵과 자사 AMR이 사용하던 Map 좌표 상에는 큰 차이가 있었으며 Update 이후에도 AMR 구동에는 문제가 없게 하기 위하여 기존에 사용하던 Node, Link 정보들은 유지하면서 새로 추가된 Node, Link를 기존 맵 좌표에 맞게 새로 맵핑하는 작업이 필요하였다.

이를 위해 ACS 맵인 엑셀 파일 파싱 후 기존 자사 맵에 등록되어있는 Node, Link인 경우 업데이트 하지 않게 하였고 새로 추가된 Node, Link인 경우 주변 Node의 x,y 좌표에 맞게 offset을 줘 Update이후에도 AMR이 구동가능 한 상태로 Update하게 만들었다.

정리

개발 기간이 촉박했을 뿐만 아니라 개발과 셋업을 동시에 진행해야 하는 상황이었다. 또한 AMR 업체가 두 개라 Map 동기화도 어려웠고 셋업 진행 중 고객사 요구사항에 맞춰 발빠르게 개발해야하는 프로젝트였다.

이 프로젝트를 진행하면서 AMR에 맞는 Solution 구조에 대해 다시 한 번 생각해보게 되었으며, 유지보수가 쉽고 고객사 요구사항에 빠르게 대응할 수 있는 구조에 대해 고민하게 되었다. 기존 자사 솔루션 ( 카페 로봇 ) 개발 시에는 CAB 구조로 각 사이트 요구사항에 맞게 UI 및 비지니스 로직 모듈만 교체해가며 대응했었는데 AMR에서는 여러 패키지들 ( ACS 통신, Scenario, 각 Device ( IO, PIO, Lidar 등등 ) )을 어떤 방식으로 결합도를 낮추고 응집력을 높일 것인지, 각 패키지와 패키지 안의 Node에 대해서도 어떤 R&R을 적용하여 설계할 것인지에 대해 고민하게 되는 계기가 된 프로젝트였다.

프로젝트명

OTIS - ACS 개발

소속/기관명

티로보틱스

프로젝트 기간

2021.09. ~ 2022.07.

프로젝트 내용

개요

앤로 ~ 티로보틱스에서 재직 중 맡았던 AGV 제어용 간이 ACS 개발 프로젝트였다.

OTIS 엘레베이터 모듈 생산공장에서 완성된 모듈을 포장대 까지 이송하는 AGV의 경로 생성 및 관제 시스템을 개발하는 프로젝트 였다.

세부 내용

  • 기간 : 2021.09 ~ 2022.07 ( 2022.02 ~ 2022.07 유지보수 기간 )

  • 개발 언어 : C#

  • 개발 환경 및 사용 라이브러리

    • .net core 3.1

    • WPF

    • Comidas ( 에어샤워 제어용 IO Board Lib )

    • Prism

    • LingoBell ( 호출 벨 수신 용 Lib )

담당 파트

AGV 목적지 설정 및 경로 설정

생산 공장에서 제품 생산 및 검수 작업이 끝난 후 포장대로 제품을 이송하기 위한 AGV의 목적지 설정 및 경로 탐색 알고리즘 개발을 담당하였다. 현장에서 제품 생산 및 검수 작업을 하는 생산대에는 AGV를 호출할 수 있는 호출벨과 제품을 실은 후 포장대로 제품을 이송하기 위한 복귀벨이 있었고 포장대에서는 이송된 물건을 내린 후 AGV를 복귀시키기 위한 복귀벨이 부착되어있었다. 또한 AGV는 바닥에 설치된 데이터 매트릭스로 자신의 위치를 인식하여 주행하는 모델이였다. 바닥에 설치된 데이터 매트릭스를 기반으로 2차원 map을 만들어서 json 파일로 관리하고 있었다.

AGV 경로 설정

Window application 실행 후 AGV와 연결되면 AGV로부터 맵을 받아와 2차원 배열에 각 포지션 마다 가중치와 함께 넣어줬다. 각 포지션에 포지션 ID, 가중치를 넣어주었다. AGV가 호출 되면 현재 위치에서 부터 호출된 위치까지 BFS탐색을 이용하여 최적경로를 찾은 후 배열에 경로를 담았다.

AGV 목적지설정

AGV의 목적지 설정을 위해 생산대에서 들어오는 호출벨들의 호출을 Queue에 담아두었다. AGV가 대기 위치에 있을 때 Queue에서 호출을 하나씩 꺼내어 경로 탐색을 통해 호출된 위치로 보냈다. 또한 대기 위치가 아닌 생산대나 포장대에서 AGV가 대기할 때는 각 포지션에 맞는 복귀벨이 눌러질 때까지 AGV가 움직이지 않도록 인터락을 걸어두었다.

아키텍쳐 설계

이번 프로젝트도 WPF와 Prism을 사용하여 아키텍쳐 설계를 하였다. 봇봇봇 프로젝트때 만들어놓았던 Common Module과 Xml, Logging Service를 재사용 하였으며 UI 용 Home Module과 장비제어용 Device Module로 분리하였다.

  • XML 및 Logging 용 Service

  • 각 모듈에서 공통으로 사용하는 이벤트, 모델, StyleDictionary 등이 있는 Common Module

  • 장비 제어용 클래스들이 있는 Device Module ( 서비스로 등록 )

  • 솔루션의 모듈과 서비스를 등록하는 Core

AGV에서 사용될 명령어들은 모두 json 형태로 넘겨줘야 했기에 팩토리 패턴을 사용하여 명령어객체들을생성할 수 있게 설계하였다.

Device 모듈 개발

이번 프로젝트에서 Home Module은 단순히 Viewing기능만 있었다. 호출 신호가 들어오면 호출 신호를 받아 Queue에 넣고 Device Module 내에서 호출 신호를 처리하여 AGV에게 명령어를 보냈다.

장비제어에 필요한 각 장비들을 각각 Model로 분리하였고 메인 로직을 담당할 DeviceService 클래스에서 각 장비의 제어를 위해 함수로 분리시켜 놓았다. 또한 DeviceService에서 비동기 작업시 여러 Thread에서 동기화를 위해 각 Model 안에서 동기화 처리를 해주었다. 이렇게 Device Service를 설계해 놓으니 고객사에서 운영상 변경할 부분이 있을때 미리 만들어 두었던 함수들의 호출 로직만 바꿔주면 되었고 각 리소스들의 동기화도 Model에 맡겨두었기 때문에 빠르게 로직을 변경할 수 있었다.

어려웠던 점

요구사항의 변경

처음 프로젝트를 시작하였을 때 고객사의 요구사항도 정리가 되어있지 않았었고 장비 납품까지 한 달정도의 시간밖에 없었다. 이를해결하기 위해 기존 프로젝트에서 재사용할 수 있는 모듈들은 소스코드 그대로 들고와 재사용 하였고 개발 후 테스트를 위해 고객사에서 테스트하던 순간에도 계속해서 요구사항이 바뀌고 있었다. 이를 해결하기 위해 각 센서,장비 별 기능을 함수로 분리시켜 따로 동작할 수 있게 설계변경을 하였고 이를 통해 로직만 변경하면 요구사항에 맞출 수 있도록 개발하였다.

AGV 용 Map의 변경

개발 후 고객사에서 장비를 테스트하고 있을 때 기획단계에서 절대로 바뀌지 않는다고 하였던 Map이 빈번하게 변경되었다. 개발 시작 당시의 기획 상 Map은 사각형 형태가 아닌 A->B로 간다고 했을때 직선상의 경로만 있는 단순한 맵이였기 때문에 fixed plan 이였고 각 목적지마다 미리 정해놓은 시나리오대로 AGV가 주행하게 설계했었다. 하지만 Map이 변화하고 운영중에도 계속 Map이 바뀐다고 기획이 변경된 이후 경로탐색을 위한 BFS 알고리즘을 적용하여 AGV의 주행경로를 유동적으로 바꿀 수 있게 알고리즘을 변경하였다.

정리

개발 기간 안에 신규 개발과 추가 개발. 두마리 토끼를 동시에 잡아야만 했었던 상황이 너무나도 힘들었던 프로젝트였다.

그렇지만 WPF, Prism 등 평소에 관심이 있었던 기술이나 분야에 대한 경험을 쌓을 수 있었고 빠른 시간 안에 개발할 때 어떻게, 무엇을 중점적으로 개발해야 할 지 조금의 노하우를 쌓을 수 있었기 때문에 기억에 남을 것 같다

프로젝트명

BotBotBot-신세계대전점

소속/기관명

앤로

프로젝트 기간

2021.05. ~ 2021.08.

프로젝트 내용

개요

앤로에서 재직 중 맡았던 신세계 대전점에 BotBotBot이 입점한 프로젝트였다.

BotBotBot 대전점은 Drink, Drip 봇으로 구성되어있다.

세부 내용

  • 기간 : 2021.05 ~ 2020.08

  • 개발 언어 : C#

  • 개발 환경 및 사용 라이브러리

    • .net core 3.1

    • WPF

    • Arduino

    • Prism

    • Universal Robot 3,5 CB series

담당 파트

드링크, 드립 Control Template 적용

이전에 진행했던 BotBotBot 성수점에서 조명 때문에 화면을 밝게 하면 모니터가 잘 보이지 않는다는 이슈가 있었어서 어두운 테마로 StyleDictionary를 구성했다.

어두운 테마의 템플릿을 새로 적용한 컨트롤에는 Grid, Combobox, Scrollbar, Slider, Border, TextBlock, TextBox, Label, Button(Radio Button, Button, 등 이 있다.

드링크 봇의 재료 관리에 사용하는 RadialMenu Custom Control을 개발하였다.

SW 아키텍쳐 설계

WPF와 Prism을 사용하게 됨으로써 기본적으로 MVVM패턴 및 모듈러 방식의 개발방법을 적용하여 개발하였다.

봇봇봇 대전점 Application은 다음과 같이 구성했다. 각각의 모듈은 BotBotBot 솔루션 안의 프로젝트 단위로 생성하였으 Service는 하나의 프로젝트안에 클래스로 분리하여 생성하였다.

  • 드링크, 드립봇의 여러 기능을 담당하는 모듈과 서비스를 등록하는 Core

  • 주문관리 및 로봇 명령어를 파싱하는 Order Module

  • 레시피를 관리하는 Recipe Module

  • 화면 이동을 담당하는 Navigation Module

  • 장비 상태 및 디버깅 용 기능이 들어가 있는 Status Module

  • 장비 제어용 클래스들이 있는 Device Module ( 서비스로 등록 )

  • 각 모듈에서 공통으로 사용하는 이벤트, 모델, StyleDictionary 등이 있는 Common Module

  • XML 및 Logging 용 Service

  • 재료를 관리하는 Material Module ( 드링크 한정 )

MainWindow 상에서 Region은 다음과 같이 나누었다.

  • 화면 이동을 담당하는 버튼들이 있는 Left Sidebar Region

  • 장비 상태 및 디버깅 용 Control이 있는 Right SideBar Region

  • Order , Recipe, Material 등 메인 화면을 구성하는 모듈을 보여주는 Content Region

BotBotBot 대전점 Application을 설계할 때 각 모듈들의 재사용성 및 확장성을 높이기 위해 많은 고심을 하였다. 공통으로 필요한 기능들은 각 모듈 안에서 인터페이스 및 추상클래스를 활용하여 반드시 구현하게 설계하였고 View내에서 자주 쓰이는 컴포넌트들은 UserControl로 구현하여 재사용하였다.

장비 제어용 모듈은 드링크, 드립에서 모두 필요했지만 동작방식이 달랐기때문에 파사드패턴을 사용하여 외부에는 Make 함수만 노출되게 하였고 각 세부 구현은 각각의 Application 내에서 다르게 구현하게 하였다.

Service 모듈 개발

XMLService

드링크, 드립 봇 모두 레시피, 재료, 설정 파일 등 로그파일을 제외한 모든 파일을 XML을 사용하여 관리하였다. 주문,레시피,재료 모듈에서 모두 XML Service를 호출하여 각 모듈에서 필요한 XML파일을 Read/Write하는 기능이 필요했다. XML Service 클래스 내부에서 각 파일 별로 Read/Write 함수를 구현하면 나중에 레시피, 재료, 설정 파일등 포맷이 바뀔 경우 각 모듈내부에서의 동작과 XML Service도 수정해야 하는 상황이 올 수 도 있었다. 이를 방지하기 위해 XML Service에서는 인터페이스를 활용하여 ReadXML, WriteXML 이렇게 두 개의 함수만 외부로 노출하였다. ReadXML 함수는 각 XML 파일 내부의 Element와 Attribute를 Dictionary의 구조로 반환하여 함수를 호출한 모듈에서 Dictionary를 파싱하여 사용할 수 있게 설계하였으며 WriteXML 함수는 Dictionary를 인자로 받아 각각의 Key, Value 값을 바탕으로 Element, Attribute를 생성하여 XML 파일에 Write하였다.

XML Service 클래스를 이렇게 설계함으로써 실제로 Recipe 파일의 구조나 새로운 Device가 추가 되더라도 XMLService는 수정할 필요 없이 각 파일을 사용하는 모듈 내부에서만 코드를 수정하면 되었기 때문에 요구사항의 변경 및 기능 변경 건에 관하여 유지보수 시간이 단축되었다.

Logging Service

비록 UI 화면에서는 Log를 보여주지 않지만 이슈 발생 시 상황분석 및 디버깅을 위해 Log를 생성할 필요가 있었다. 각각의 모듈에서 Logging Service를 호출하여 사용하여야 했기에 Thread-safety하게 구현을 해야 하였다. 이를 위해 외부로 LogWrite함수만 노출시킨 후 LogWrite 내부에서 ConcurrentQueue를 이용하여 각 모듈에서 받아온 로그를 Enqueue 후 Service 내부에서 StreamWriter를 사용하여 텍스트 파일 형식으로 로그를 기록하였다.

각각의 Service들은 Application과 생애주기를 같이하기에 Application 초기화 시 Service Register 단계에서 프리즘에서 제공하는 기능을 사용하여 싱글턴으로 객체를 등록하였으며 모듈 생성시 Service 객체들을 각각의 모듈에 등록하여 주었다.

Common 모듈 개발

봇봇봇 솔루션에서는 각각의 모듈들이 서로 통신할 수 있게 옵저버 패턴으로 구현되어있는 Prism에서 제공한 EventAggregator를 사용하였으며 이를 사용하여 Event기반의 느슨한 구조로 결합하였다.

Common 모듈에서는 각 모듈간의 통신을 위한 Event Class들과 드링크, 드립 봇에서 동일하게 사용할 수 있는 모델들이 정의되어있다. Common 모듈 안에서의 모델들은 IOrderModel, IRecipeModel 등 인터페이스로 정의되어 있다.

또한 각 모듈의 View에서 동일한 테마로 사용할 수 있게 여러 컨트롤들의 Template들을 재정의 해놓은StyleDictionary도 Common 모듈 안에 작성해두었다.

Device 모듈 개발

드링크, 드립 봇은 각각 사용하는 장비에 차이가 있었다.

드링크 봇의 경우 제빙기(2EA), Universal Robot 5 CB-Series, Digital I/O 제어를 위한 아두이노를 사용하였으며 드립봇의 경우 Universal Robot 3 CB-Series, 아두이노, 로드셀과의 통신을 위한 인디케이터 등을 사용하였다.

Order 모듈에서 주문을 받고 레시피 기반의 음료 제조를 위한 명령어를 만들어서 Device 모듈의 Make 함수를 호출하면 Device 모듈 내부에서 각각의 장비 타입에 맞게 동작을 하였다. 이를 위해 Device모듈은 파사드 패턴을 사용하여 설계하였으며 외부에는 MakeStart, MakeStop, DeviceReset 이 세개의 함수만 노출시켰다.

Device 모듈은 Application 초기화 단계에서 모듈카탈로그에 등록하지 않고 싱글턴패턴을 사용하여 Service로 등록하였으며 각 모듈에서 Device 객체를 Service 타입으로 각 모듈에 등록하였다.

어려웠던 점

공통 기능 재사용성 및 유연성 뛰어난 Application 설계

드링크 봇 및 드립 봇 공통으로 로봇 프로그램 및 사용하는 장비를 제외한 기능은 동일했다. 주문받은 메뉴를 표시하고 제조 목록에 메뉴를 올려 제조 시작 / 제조 중지 / 장비 리셋 등 작업자가 조작할 수 있는 버튼 구성 등 UI구성도 비슷했고 동작도 비슷했다.

이를 각각의 장비타입에 맞게 Application 별로 새로 코딩하기에는 시간도 부족하고 유지보수 측면에서도 좋지 않았다.

이를 해결하기 모듈러 개발 방식을 채택하게 되었다. Order / Recipe 모듈에서의 View 구성 및 바인딩은 드링크, 드립 봇이 동일하게 진행되었고 ViewModel에서 바인딩 한 모델은 Common Module의 Model을 상속하는 새로운 Model만 사용하여 드링크, 드립 봇의 차별점을 두었다. 이를 통해 만약 새로운 타입의 장비를 만들게 된다면 속된 말로 찍어내듯이 빠르게 Application 개발이 가능하게 되었다.

또한 View에 바인딩 된 모델과 Command는 드링크 봇과 드립 봇이 동일했기에 Command 내부에서 드링크, 드립 봇의 세부적인 명령어 및 Recipe 파싱 등 Model 상태를 변화시키고 음료 제작을 위해 명령어를 만들 때 Model에 구현해 놓은 비지니스 로직만 바꾸면 되었다.

모듈러 방식의 개발은 경험해보지 못했던 방식이였기에 처음에 모듈 별로 기능을 나누고 외부로 노출시켜줄 인터페이스 및 동일 기능을 위한 추상클래스로의 분류 작업이 힘들었다.

하지만 모듈단위의 유닛테스트와 재사용성, 확장성이 뛰어난 모듈 설계를 바탕으로 빠른 시간안에 두 개의 장비 Application을 개발할 수 있었다.

Control Template 재정의 및 Custom Control 응용

WPF에는 기본 컨트롤들의 Data Template 및 ItemsPanelTemplate, Control Template을 재정의 할 수 있었다. 하지만 기본 컨트롤들의 구조와 Trigger에 대해 잘 알지 못했었기 때문에 처음 개발을 시작했을 때 작업속도가 많이 느렸었다. 다행히도 MSDN에 각 컨트롤들의 구조에 대한 문서가 있었고 예전 QML을 사용하여 UI를 구성해봤던 경험으로 컨트롤 하나하나 Template을 새로 적용할 수 있었다. WinForm과는 다르게 Template을 적용하고 나서 부터는 xaml에서 Style지정만 해주면 되었기에 프로젝트 전체로 봐서는 오히려 UI 작업속도가 향상되었었다.

하드웨어 외주 회사와의 커뮤니케이션 문제

본부 내에 하드웨어 팀이 따로 없었고 턴 키 형태로 외주를 맡겨 하드웨어 설계를 진행하게 되었다.

턴키 방식으로 외주를 맡기다 보니 이메일, 전화, 카카오톡 으로 커뮤니케이션이 이루어질 수 밖에 없었고 외주회사의 위치가 경상북도 구미였기 때문에 매주 개발회의를 하기도 힘든 상황이었다. 메일로 미리 설계자료를 받고 거기에 맞춘 로봇 티칭 및 비지니스 로직을 설계했었는데 결국 장비가 들어왔을때 미리 협의된 설계내용과 오차가 있는 부분이 있었다. 프로젝트 일정 상 결국 음료 제조를 위한 로직을 변경하는 방법밖에 없었고 이 때 모듈러방식 개발의 장점을 확인할 수 있었다.

정리

그동안 WinForm 기반의 프로젝트들을 많이 수행했었는데 WPF와 Prism을 사용해보니 확실히 유지보수 측면에서의 많은 장점이 보였다. 특시 모듈 방식의 개발은 다른 프로젝트를 수행하더라도 몇 개의 모듈은 가져다 쓸 수 있을 정도로 확장성과 재사용성에 있어 엄청난 이점을 확인할 수 있었다.

또한 WPF 내부 컨트롤들의 구조나 기존 프로젝트들에서 시간을 꽤 많이 빼앗겼던 UI와 관련한 작업들에 대해 빠른 시간안에 퀄리티 좋은 Application을 개발할 수 있겠다는 자신감을 심어주었던 프로젝트였다.

MVVM 및 파사드, 추상 팩토리, 싱글턴, 옵저버 패턴 등 다양한 패턴을 실제 프로젝트에 적용하여 사용해볼 수 있는 기회가 되었고 평소 관심있던 기술과 패턴들을 사용해볼 수 있어서 이때까지 진행했었던 프로젝트 중 가장 성취감이 뛰어난 프로젝트였다

프로젝트명

ICTK-VISA

소속/기관명

앤로

프로젝트 기간

2021.06. ~ 2021.07.

프로젝트 내용

개요

앤로에서 재직중 맡았던 VISA 단말기 검증용 Application 유지보수 프로젝트였다.

기존 고객사에서 요구사항 변경으로 인한 Application 업그레이드가 필요하여 닷넷 버전 마이그레이션 및 요구기능 추가를 진행한 프로젝트이다.

세부 내용

  • 기간 : 2021.06 ~ 2021.07

  • 개발 언어 : C#

  • 개발 환경 및 사용 라이브러리

    • .net framework 4.7.2

    • WinForm

    • VISA WCF Service Reference

    • Universal Robot5 CB-Series

    • Arduino

    • AccessDatabaseEngine

    • Microsoft Excel 2019

담당 파트

Test Position 변경 및 Position ID 추가

각 테스트 포지션 별로 Position ID를 추가하고 포지션 별 Z Offset을 추가했다. 기존 프로젝트에서 Test Position을 엑셀 파일로 관리하고 있었기 때문에 엑셀에서 Row 하나를 추가하여 Test Position 별로 Position ID를 추가했다. 추가한 Position ID는 각 Position 별로 고유한 ID였기에 이를 Position Class에 멤버변수 하나를 추가하여 const 변수로 관리했다.

포지션 별 Z Offset은 단말기 외관상 테스트 할 수 없는 Position은 Offset을 적용하여 조금 아래로 내리거나 조금 위로 올릴 수 있게 Offset 설정을 따로 할 수 있게 변경하였으며 테스트 실행 시 로봇 포지션 계산 시 이를 반영하여 계산했다.

단말기 테스트 시 Card Fail Code 변경 및 Error 상황 시 동작 변경

기존 테스트 시에 카드 결제 Fail 시 Fail 코드가 여러 개 존재했었다. 하지만 추가 요구사항에는 Pass or Fail 만 있었고 테스트 시 여러 Fail Case를 삭제하였다. 또한 기존 테스트 시에는 Error 상황 발생 시 리셋 후 다시 처음부터 시작하여야 했다. 테스트 카드가 500여장 가까이 되고 전체 카드 테스트 시 24시간 내내 장비를 돌려도 5일 정도 걸리는 것을 감안하면 매우 비효율적인 방법이였고 Error 발생 후 리셋 시 이전 테스트 카드와 테스트 포지션부터 다시 테스트 하는 것이 요구사항에 들어가있었다.

기존 프로젝트에서는 DB를 엑셀로 사용하였으며 엑셀로 관리하는 파일은 Position, Test Session, Cards, Result이렇게 4개가 있었다. 이 중 Test Session에 카드의 테스트 유무, 현재 테스트 카드 및 현재 테스트 포지션을 기록하는 Column을 추가하였고 이를 이용하여 Error 상황시 이어하기 기을 개발할 수 있었다. 또한 Application을 강제종료 한 상황 및 Application을 종료하지 않았을 때 시간을 최소화 하기 위해 App 내에서도 Cards, Test Sesstion Class 에 내부변수로 기록해 두었다.

Test Result 포맷 변경

VISA의 테스트 결과 템플릿 변경으로 인하여 불가피하게 장비의 템플릿도 변경하게 되었다. Test Session에서의 각 카드 별로 DataGridView를 이용하여 포지션별 테스트 값을 저장하였으며 Card하나의 테스트가 끝나면 DataGridView의 내용을 VISA 테스트 결과 템플릿에 맞춰 데이터 파싱 후 엑셀에 즉시 저장하였다.

Middleware 변경으로 인한 동작 시퀀스 변경

기존 테스트 장비에서는 카드 단말기와 PC Application이 다이렉트로 연결되어 있었다. 하지만 결과 검증 및 데이터 신뢰성을 높이기 위해 VISA Middleware가 추가되었다. "PC Application <-> VISA Middleware <-> 테스트 단말기"의 형태로 장비구성이 이루어지게 되었고 VISA 측에서 제공 받은 WCF ServiceReference를 사용하여 Middleware와 통신하는 모듈을 개발하였다.

어려웠던 점

개발 도중 계속 바뀌는 요구사항

개발 기간이 두 달이였지만 프로젝트 종료 일주일 전까지도 요구사항이 계속 변경되었다. 구조설계부터 새로 할 수 있는 프로젝트가 아니었고 계속 변경되는 요구사항에 맞춰 빠르게 개발하기 위해 각 기능별로 함수로 전부 분리해두었다.

다행히 개발이 거의 마무리 되어갈 즈음에는 미리 구현해둔 함수를 요구사항에 맞게 로직을 짜는 수준으로 빠르게 개발할 수 있는 상황이 되었고 일정에 맞춰 프로젝트를 완수할 수 있었다.

기 개발된 프로젝트와 호환성 유지

프로젝트의 요구사항 변경에 맞춘 유지보수 건이였지만 고객사 측에서 기존에 사용하던 프로그램과의 호환성을 원했다. 제일 좋은 방법은 아키텍쳐 설계부터 다시 하여 구버전 및 신버전에 맞는 새로운 Application을 개발하는 것이었지만 프로젝트 마감 기간이 거의 다되서 요구사항이 수정되었기 때문에 개발 기간의 부족으로 인해 불가능한 상황이었다.

이를 위해 예전 CafeBot 프로젝트에서 사용했던 Upgrade 및 Downgrade버튼을 추가해 고객사 측에서 사용할 용도에 맞게 프로그램을 새로 실행시키는 방법으로 해결하였다.

정리

앞서 설명한 대로 요구사항이 계속 변경되고 개발 기간조차 두 달로 매우 짧은 프로젝트였다.

하지만 WCF 및 엑셀을 DB로 사용해보고 기존에 접해보지 못했던 기술을 다뤄봐서 개인적으로는 만족도가 큰 프로젝트였다

프로젝트명

서빙로봇 Avoidence 모듈 개발

소속/기관명

앤로

프로젝트 기간

2021.02. ~ 2021.03.

프로젝트 내용

개요

앤로에서 재직중 맡았던 서빙로봇 회피모듈 개발 프로젝트였다.

서빙로봇에 부착된 RealSense 카메라를 통해 Depth Data를 취합 후 로봇 좌표에 맞춰 변환 및 필터링을 거쳐 각도별 물체 탐지를 하는 모듈 개발을 진행했다.

세부 내용

  • 기간 : 2021.02 ~ 2021.03

    Comment

  • 개발 언어 : C++

    Comment

  • 개발 환경 및 사용 라이브러리

    • ROS2 Dashing

      Comment

    • Jetson Xavier NX

      Comment

    • Librealsense SDK 2.0

      Comment

    • Opencv 4.1

      Comment

    Comment

담당 파트

카메라 뎁스 데이터 변환

서빙 로봇에 장착되어있는 인텔 리얼센스 D435 카메라 2개의 뎁스 데이터를 취합하여 Robot Base 기준 좌표로 변환하여 각도별 물체 탐지를 하는 모듈 개발을 맡았다.

전방 장애물 감지 및 회피기동을 위해 인텔 리얼센스 D435 카메라 두 개로 부터 640*480 해상도의 프레임샷을 받아왔다. D435 카메라로 부터 초당 40프레임의 뎁스 데이터가 들어왔다. 각각의 카메라에서 들어온 뎁스 데이터들을 로봇 기준 좌표계로 변환 후 필터를 통과시킨 후 ROS Topic으로 변환하는데 까지 20~30fps가 됐어야 했는데 기 개발된 모듈은 70~80fps 가 나왔다.

기 개발된 모듈을 분석했을 때 여러가지 문제점들이 보였다. opencv를 사용하긴 했지만 CPU를 사용하여 뎁스 데이터 연산을 하고 있었으며 카메라 데이터들이 겹치는 공간을 연산 후 제거하는 게 아닌 임의로 데이터들을 제거 후 연산하고 있었다. 당연히 로봇 좌표로 변환 전 카메라 좌표계 기준으로 데이터를 자르고 변환 후 사용해서 오차가 컸고 많은 뎁뎁스 데이터를 CPU연산으로 진행했기 때문에 성능도 나오지 않았다.

먼저 카메라 모듈 안에서의 기능 분리를 위해 인텔 리얼센스 카메라에서 Frame을 가지고와 행렬로 변환하는 shot class와 GPU연산을 담당하는 avoid class로 분리하였다.

Shot Class

shot class 에서는 RealSense SDK를 사용하여 각 카메라에서 들어온 프레임에서 뎁스 데이터를 추출 후 각 픽셀 당 x,y,z값이 들어가 있는 vertices로 변환하였다. vertices로 변환된 cv::Mat을 Avoid 객체에 포인터로 넘겨주었다.

Avoid Class

GPU 연산을 진행하기 전 각 카메라 좌표계 기준으로 들어오는 뎁스 데이터를 로봇 기준 좌표의 데이터로 변환하기 위해 각 카메라 별로 좌표 변환 행렬을 만들었다. 또한 아직 개발중인 장비였기 때문에 카메라의 위치가 바뀔 수도 있어 로봇 중심으로 부터의 거리, x,y,z 축으로의 회전 각도를 클래스 내부 변수로 선언해놨으며 카메라 위치 변경 시 거리,x,y,z 축 값만 변경하면 카메라 모듈이 정상 동작하도록 변경하였다.

avoid class 에서는 shot class로부터 받은 행렬을 이용하여 GPU연산을 진행하였다. cv::cuda::gemm을 사용하여 만들어둔 좌표 변환 행렬과 GPU에 업로드 한 행렬간의 연산을 진행하였으며 각 카메라 프레임에서 들어온 뎁스 데이터의 변환이 끝나면 두 데이터를 Merge하였다.

Merge한 행렬의 각 픽셀별로 로봇 중심으로 부터의 x,y,z 거리 및 x,y 거리, x,y angle값을 각 픽셀별로 계산하여 CPU로 다운로드 하였으며 반복문을 사용하여 로봇 좌표 기준 각도별로 가장 짧은 x,y거리를 가 픽셀의 x,y angle, x,y,z 거리 값을 행렬화 하였다.

기존 CPU연산을 GPU 연산으로 바꾸고 나서 70~80fps 가 나오던 모듈의 성능을 14fps ~ 28fps로 줄일 수 있었다.

어려웠던 점

좌표 계산

로봇 좌표계는 로봇 기준 정면이 x축, 왼쪽이 y축이였다. 각 카메라 뎁스 데이터를 로봇 좌표계로 변환 후 로봇 기준 각도 계산이 가장 어려웠다. x,y,z 거리값 및 x,y 거리값은 항상 양수로 나왔지만 각도같은 경우 -90° ~ 90° 의 각도 안에서 나와야 했다.

cv::cuda의 cartToPolar 함수를 사용하여 x,y 거리 및 각도값을 계산하였다. cartToPolar 함수는 atan2로 angle값을 계산했으며 atan2의 범위는 -180° ~ 180°도 이다. 뎁스 데이터를 변환한 로봇 좌표계에서 알 수 있듯이 1,4분면의 각도값이 나왔으며 이를 다시 로봇 정면을 0° 로 했을 때의 각도로 변환해줘야 했다.

결국 cv::cuda 내의 함수로 해결할 수 없었으며 이를 해결하기 위해 GpuMat을 Mat으로 변환하며 CPU로 다운로드 했고 변환된 행렬을 for문으로 반복문을 돌리면서 각도값 변환 작업 및 각 각도값 별로 가장 짧은 x,y거리를 찾고 그 x,y거리값에 해당하는 x,y,z 거리값을 다시 행렬화 해주어야 했다.

이번 프로젝트에서 내부 지원 없이 OpenCV 공식 문서와 구글 검색을 통해 혼자 개발 및 검증을 진행하여야 했기에 많은 어려움이 있었다.

정리

모듈 설계부터 구현, 검증까지 전반적인 개발업무를 지원 인력 없이 단독으로 담당하여 수행하다 보니 많은 시행착오를 거치며 개발하여야 했다. 하지만 이론으로만 생각해보던 단위테스트를 실제 프로젝트에 적용해 볼 수 있었기 때문에 개인적으로는 큰 의미가 있었던 프로젝트였다.

또한 실제로 행렬 연산 및 좌표 변환 알고리즘 등 많은 수학공식들을 C++로 번역하면서 좌표 변환, 계산 및 영상 처리에 대해 자신감이 생기게 된 프로젝트였다

프로젝트명

BotBotBot 리뉴얼

소속/기관명

앤로

프로젝트 기간

2020.02. ~ 2020.05.

프로젝트 내용

개요

티로보틱스의 자회사인 앤로로 전입 후 맡았던 Cafe Bot 프로젝트의 리뉴얼 프로젝트였다.

리뉴얼 후 카페의 이름은 봇봇봇으로 변경되었다.

세부 내용

  • 기간 : 2020.02 ~ 2020.05

  • 개발 언어 : C#

  • 개발 환경 및 사용 라이브러리

    • .net framework 4.5

    • WinForm

    • FAS_EziMOTIONPlusR

    • DeviceNet

    • ObjectListView

    • AsyncBasicSocketLib

    • Universal Robot 3,5 CB series

담당 파트

드립 봇 기능 개선

기존 개발 한 드립봇에는 두 개의 리니어 모터를 사용하여 컨베이어가 두 개(A트랙, B트랙)가 있었다. 각 컨베이어 당 드립 커피를 한 번에 최대 3잔씩 뽑을 수 있었다. 또한 한 쪽 컨베이어에서 드립 커피를 추출하고 있을 땐 반대 쪽 컨베이어는 아무 동작도 하지 않게 인터락을 걸어놨었다.

주문이 3잔 이하였을 땐 괜찮았지만 주문이 4잔 이상 들어올 경우 택 타임이 너무 길어 손님들의 불편함이 너무 컸었다. 리뉴얼 때 컨베이어의 인터락을 해제하고 드립커피 추출 시의 택타임을 줄였다.

MainForm 에 있던 모터 제어 소스에서 flag를 제거하고 각 모터별 동작을 분리시켰다. 또한 레시피 대로 로봇 명령어를 만드는 부분을 기존 ConcurrentQueue 하나에서 두 개로 분리하였다. 각 Queue마다 트랙 별로 커피 제조를 위한 명령어를 담고 Queue Count를 기준으로 번갈아 가며 커피 제조를 실행하였다.

병렬 진행으로 변경 전 택 타임은 2잔 7분 16초, 4잔 8분 14초, 6잔 6분 34초에서 변경 후 2잔 4분 3초, 4잔 4분59초, 6잔 6분 19초로 트랙당 1잔 또는 2잔씩 진행하는 경우 41% 가량 택타임이 감소했다.

디저트 봇 기능 개선

디저트 봇은 케잌 위에 로봇이 미리 정해진 도안을 그려주는 로봇이다.

디저트 봇의 경우 케잌의 상태에 따라 드로잉 품질이 많이 차이가 났다. 디저트 봇이 드로잉 하기 위해서 케잌 표면과 시럽이 나오는 디스펜서와의 마진이 1~2mm정도밖에 되지 않았 드로잉 하는 케잌이 무스케잌이였기 때문에 냉동실에서 냉장고로 옮겨서 보관하고 시간이 조금만 지나도 케잌이 무너져서 드로잉이 제대로 되지 않았다.

이를 보완하기 위해 로봇 엔드이펙터 쪽에 레이저 센서를 하나 부착하여 케잌 표면을 스캔 후 케잌 표면의 높이에 맞게 로봇 스크립트를 수정하는 부분을 추가 개발하였다.

기존 디저트 봇은 미리 정해진 높이에 맞춰 그림을 그렸기 때문에 케잌의 상태에 맞게 스크립트 수정이 불가능 했지만 로봇 스크립트를 케잌마다 수정하여 로봇에 전달하여 그리는 방식으로 변경 후 드로잉 불량률이 23%에서 7%까지 감소하게 되었다.

UI 인터페이스 개선 ( 공통 )

기존 카페의 조명이 너무 밝고 장비 Application의 색이 밝은 색이였기 때문에 조명때문에 화면이 잘 안보인다는 이슈가 있었다. 또한 로봇이 메뉴 제작을 하기 까지 작업자의 많은 작업이 필요했기 때문에 이를 축소하는 작업을 했다.

전체적으로 어두운 테마를 적용하였으며 작업자들이 사용하지 않는 로그, 알람 폼을 삭제하고 자동 업그레이드, 다운 그레이드 등 기능을 제거하였다. 또한 부가 기능은 Panel width를 조절하여 숨김/표시 기능을 넣었으며 ObjectListView를 사용하여 바인딩 했던 작업리스트 또한 UserControl을 사용하여 모델 바인딩을 진행하였다. 장비의 진행 상태에 따라 BorderColor를 노란색, 초록색, 빨간색 등으로 표시하여 작업자들이 한눈에 장비 상태를 보기 쉽게 개선하였다

어려웠던 점

실시간으로 변경되는 로봇 제어 스크립트

드립봇의 경우 로봇을 제어하는 명령어가 로봇 동작중 바뀌어야 했고 디저트 봇의 경우 로봇의 동작을 제어하는 로봇 스크립트가 실시간으로 변경되야 했다.

로봇 스크립트를 변경하려면 로봇 프로그램을 리로드 해야 했다. 하지만 로봇 프로그램을 리로드 하면 로봇의 상태를 체크하는 쓰레드에서 에러코드를 리턴하게 되고 로봇은 즉시 정지 및 장비 Application에서는 에러메세지를 띄우게 처리해놨는데 이를 해결하는게 힘들었다.

로봇에 스크립트를 전송할 때 잠시 쓰레드를 대기 상태로 묶어두고 스크립트 전송 완료 및 로봇의 상태가 정상이 되면 다시 쓰레드를 살려서 에러상태에 빠지는 것을 해결했다.

또한 디저트 봇의 경우 로봇 도안별로 로봇의 높이를 결정해야 했는데 케잌 위에 레이저 센서로 점 9개를 찍어 각각의 구역별로 점과 점 사이의 값을 증가 또는 감소값을 필터링 하여 각 도안의 포인트 위치에 맞는 Z값을 설정하게 알고리즘을 구현하였다.

드립 봇 레시피에 따른 맛 변화를 최소화하 알고리즘 설계

드립 봇의 경우 로봇이 항상 일정한 맛과 향을 내는 드립커피를 추출하는 것을 핵심으로 삼고 있었고 기존 트랙 하나만 드립커피 제작에 사용하던 것을 변경하려니 드립 커피의 맛과 향의 변화가 이슈가 되었다.

이를 위해 바리스타와 함께 여러 테스트를 진행하였다. 드립커피는 트랙 두 개를 동시에 사용할 시 최대 6잔까지 가능했는데 각 드립 커피가 불림,1차추출,2차추출 ... n차 추출까지 진행하고 있을 시 현재 추출하고 있는 추출 차수 및 드립 커피의 물양 및 추출 시 대기시간을 고려하여 추가 주문 시 로봇 명령어를 수정하는 알고리즘을 개발하였다.

여러 개의 레시피 및 레시피 안에서 추출 차수 마다 물량 , 대기시간이 전부 다 달랐기 때문에 경우의 수가 너무 많아졌었다. 결국 항상 레시피 대로 제조하는 알고리즘의 개발은 하지 못했지만 추출 후 대기시간을 레시피 상의 대기시간과 오차가 가장 적은 알고리즘으로 변경하고 드립 커피의 레시피도 조절하여 최대한 맛과 향이 일정한 드립커피를 제조하는 방식으로 알고리즘을 개발했다.

정리

기존 카페 봇 오픈 당시에 있었던 소프트웨어 인력들이 대거 이탈하여 나를 포함한 후배 개발자 한 명까지 두명이서 리뉴얼을 진행하였다.

하지만 카페 기획 단계에서부터 둘 다 개발에 참여했었기 때문에 리뉴얼할 때 알고리즘 설계 말고는 딱히 어려움을 느꼈지는 않았다. 아키텍쳐부터 새로 설계하여 MVP 패턴을 적용한 Application으로 바꾸고 싶었지만 기획팀 및 운영팀과의 장비 기능 조율 및 인테리어 변경으로 인한 테스트 시간이 부족하여 기능 오류를 최소화 하는 방향으로 개발하게 되었다.

프로젝트명

Cafe Bot

소속/기관명

티로보틱스

프로젝트 기간

2019.04. ~ 2019.12.

프로젝트 내용

개요

로봇과 사람이 협업하는 컨셉의 Robot Cafe 프로젝트

기존 회사에서 많이 쓰였던 Universal Robot 을 이용한 테크 미디어 아트 공간인 Cafe Bot Sofeware를 전담하였다. 카페봇에는 칵테일 및 에이드를 제조하는 드링크 봇, 드립 커피를 제조하는 드립 봇, 케잌 위에 그림을 그려주는 디저트 봇이 있다.

세부 내용

  • 기간 : 2019.04 ~ 2019.12

  • 개발 언어 : C#

  • 개발 환경 및 사용 라이브러리

    • .net framework 4.5

    • WinForm

    • FAS_EziMOTIONPlusR

    • DeviceNet

    • ObjectListView

    • AsyncBasicSocketLib

    • Universal Robot 3,5 CB series

담당 파트

주문 관리 파트 개발

POS에서 결제 후 서버에서 Drink, Drip, Dessert로 들어오는 주문 관리 파트를 맡았다. POS 와 연동 되어 있는 서버에서 주문을 취합한 후 각 장비로 주문을 보내주면 각 장비에서 주문을 ListView에 매핑하여 화면에 Viewing 해주었다. 서버에서 장비로 주문을 보낼 때 String으로만 보냈었는데 String을 파싱하여 OrderModel을 만들어 ListView에 맵핑하였다. ListView에 Model을 바인딩 할 때 ObjectListView 라이브러리를 사용하였다.

Serial 장비 통신 모듈 개발

Cafe Bot의 Drink, Drip, Dessert 봇 에서 사용하는 서보모터, 제빙기, 리버스탭의 I/O모듈과의 통신 모듈 개발을 담당했다.

서보 모터의 경우 FAS_EziMOTIONPlusR 라이브러리를 사용하였으며 고속이동이 필요한 상황이 아니였기 때문에 펄스제어로 서보모터를 운용하였다.

제빙기, 리버스탭의 경우 각 장비사에서 제공하는 라이브러리가 있었으며 라이브러리를 사용하여 제어할 경우 장비 내부에서 상태체크를 위해 Thread를 생성하여 돌리는 방식으로 제작하셨다고 했다. 라이브러리를 사용하여 제어할 경우 장비의 Thread와 라이브러리를 사용하여 보낸 명령어의 충돌로 인해 장비가 멈추는 경우가 잦았다. 결국 장비사에 프로토콜사양을 요청하여 기 개발된 라이브러리가 아닌 개별 명령어를 사용하여 장비를 사용하였다. 예를 들어 제빙기 같은 경우 통신모드로 설정 후 장비사에서 제공하는 라이브러리를 사용하여 출빙 명령을 보내면 제빙기의 상태값이 들어오게 되고 그 후 출빙이 진행되었다. 그 다음 출빙 명령을 보내게 되면 제빙기의 상태값이 들어오는게 아닌 이미 상태체크를 진행중이라는 메세지와 함께 제빙기가 멈춰버리는 이슈가 있었다. 이러한 이슈 때문에 장비사에 연락하여 직접 제빙기로 출빙 명령을 보내는 프로토콜 사양서를 받았고 이를 사용하여 제빙기 제어용 클래스를 따로 생성하여 제어하였다.

컨텐츠 Application 모듈과의 통신모듈 개발

카페 봇에는 Drink, Drip, Dessert 봇 뿐만이 아니라 Drink, Drip 봇 과의 연동이 되는 컨텐츠 들이 있었다.

Drip Bot 컨텐츠의 경우 평상시에는 각 메뉴들에 대한 설명 및 날씨, 온습도 등이 표시되었으며 그에 맞는 컨텐츠들로 채워졌었다. 또한 드립커피 제조 시에는 메뉴 명, 드립 방식 등 메뉴에 맞는 컨텐츠들로 변경되며 표시 된다.

Drink Bot 컨텐츠의 경우에도 평상시에는 메뉴판역할을 하며 드링크 제조 시에는 각 메뉴의 대기번호, 제조상태, 쉐이킹 모션등이 표시되었다.

2019년 7월에 카페 봇을 오픈하고 로봇의 오동작이 잦았다. 이는 적절한 TCP(Tool Center Point) 설정 실패 및 payload 문제때문에 잦은 Protective Stop이 발생해서 였다. 또한 반도체 장비처럼 일정한 환경의 클린룸에서 장비가 동작하는게 아닌 상시 변화하는 환경 내에서 동작하는데 이 환경변화를 생각하지 않고 개발해서 오류가 잦았었다. 당시 Protective Stop의 원인에는 joint limit에 걸리거나 장비 근처의 시럽이나 물기 때문에 미끄러짐 등 외부 환경에 의한 오류, 작업자의 미숙한 장비 사용 등 원인이 너무 복합적이고 많았었다.

이를 해결하기 위해 Universal Robot에 오류가 발생하면 즉시 로봇에 부착되어있는 모니터의 화면을 캡쳐하고 장비 log를 백업용 FTP 서버에 백업하는 모듈을 개발했다.

로봇 화면을 캡쳐하는 프로그램은 Linux 기반의 Univeral Robot PC 안에 String 을 받아 화면을 캡쳐 후 다시 Server로 캡쳐한 사진파일을 전송해 주는 Client를 개발하였다. 이 캡쳐용 Client와 통신하는 Server는 장비 Application에 추가하여 로봇의 상태를 장비 Application에서 확인 후 로봇 내부의 Client에 메세지를 보내면 로봇내부의 Client가 화면을 캡쳐하여 Server로 다시 전송해주는 방법을 사용하였다. 로봇 내부의 TCP Client는 Python을 이용하여 개발하였고 장비 Application의 TCP Server는 C#을 사용하여 개발하였다.

로그 분석기는 각 장비에서의 Log파일을 취합하여 헤더 별로 Normal, Warning, Error 상태 중 어떤 상태인지 분류한 후 Warning, Error인 경우 원인별로 Log 갯수를 취합하여 ListView에 Log별로 뿌려줬다. 로그 분석기를 도입하기 전 정확하게 어떤 에러가 얼마나 일어나는지 정량적으로 확인하기 어려움이 많았는데 로그 분석기를 도입한 후 어떠한 에러가 왜 나는지 정확하게 원인 분석 후 해결하는 식으로 이슈 대응 방식이 바뀌어 이슈 대응에 많은 시간이 절약되었다.

원격 업데이트 및 다운 그레이드 모듈 개발

매장 내 장비들의 잦은 오류로 인해 소스코드를 빌드하고 다시 매장으로 가 빌드된 파일들을 배포하고 하는 것에 시간이 너무 많이 사용되었다. 이를 해결하기 위해 FTP 서버 구축 후 배포파일들의 버전관리를 시작하게 되었다. 사무실에서 빌드 후 FTP서버에 올리면 매장 내 장비에서 프로그램 실행 시 버전을 확인하고 업데이트 후 오류 조치 내용들을 반영하게 하였다. 업데이트 후 문제가 생기지 않던 부분에서 문제가 발생하기도 하고 소스코드 수정을 잘못한 후 업데이트가 되기도 하여 업데이트 시 버전 선택 후 원하는 버전으로 실행 하는 업데이트 및 다운그레이드를 하는 런처기능을 추가 개발하였다.

어려웠던 점

짧은 개발기간 및 하드코딩

프로젝트 내에 Software 인원은 팀장 1, 팀원 4 였지만 팀장님과 나를 제외한 나머지 3명은 신입사원이여서 크게 기대를 하기 어려운 상황이였다. 팀장님 또한 협업하는 다른 회사와의 일정 조율 및 요구사항 조율, POS 및 장비 선정 등에 많은 시간을 쏟으셔서 인원이 절대적으로 부족한 상황이였다.

프로젝트 기획부터 요구사항이 정리되고 개발기간 및 매장 오픈까지 3개월의 시간이 있었다. 짧다면 짧고 길다면 긴 시간이지만 3개월 동안 많은 파트를 맡아 개발하면서 역량 부족을 뼈저리게 느끼게 된 프로젝트였다.

주문 관리 파트, 주문과 레시피를 파싱하여 로봇 명령어를 만드는 파트, 로봇이 음료 및 케잌 위에 드로잉을 하기 까지의 많은 인터락 및 알고리즘 개발 파트, 재료 및 레시피 관리 파트 등등 짧은 시간 안에 개발해야 할 양이 많아 기능 구현 및 적용에 초점을 맞춰서 개발하다 보니 Application의 전체 아키텍처 및 디자인 패턴 등을 설계, 적용할 시간도 없이 기능 구현에 초점을 맞췄었다.

기능 구현에 초점을 맞췄음에도 불구하고 에러 상황에 대한 대처, 제일 중요한 로봇 스크립트 개발 등 소홀했던 부분도 많고 결과적으로 2019년 7월에 매장을 오픈하고 2019년 12월까지 6개월 가량 거의 매일 이슈가 하나 이상씩은 생겼으며 결국 2020년 2월 리뉴얼을 결정하게 되었다.

Universal Robot / 하드웨어에 대한 이해 부족

Universal Robot을 이전 프로젝트에서도 사용해 봤지만 로봇에 대한 이해 및 논리적인 설계 없이 각 기능 구현과 티칭에 초점을 맞추다 보니 TCP, payload에서부터 문제가 발생하여 신뢰도가 없는 장비가 만들어졌다.

SW의 기능이 잘 되고 Robot이 내가 원하는 위치로 잘 움직인다고 제대로 개발 된 Application이 아니라고 느끼게 되었다. 하드웨어의 설계에 따른 올바른 동작 및 주변 상황도 고려하여 유연성 및 확장성 있는 프로그램을 개발하고, 주어진 비지니스 문제에 대한 파악이 먼저라고 느꼈다.

정리

개발자에 대한 내 관점을 바꾸게 된 프로젝트였다.

단순히 정해진 요구사항대로 잘 동작하는 소프트웨어, 예외처리 및 쓰레드 관리를 잘 하여 죽지 않는 좀비 프로그램 만들지 않기, 좋은 성능을 내며 메모리에 최적화 된 프로그램을 만드는게 개발자가 아니라 주어진 비지니스 문제를 분석 및 파악하여 최소한의 비용으로 최대한의 효과를 내게 하는 것이 좋은 개발자라는 생각을 가지게 되었다.

이번 프로젝트를 기점으로 디자인 패턴 및 C#이라는 언어스펙에 관하여 깊게 공부를 시작하였으며 개발자로써의 내 역량 부족을 느끼고 반성하게 되는 계기가 되었던 프로젝트였다.

프로젝트명

AGV용 Master Program

소속/기관명

티로보틱스

프로젝트 기간

2018.09. ~ 2018.12.

프로젝트 내용

개요

AGV개발을 위한 내부 디버깅 용 프로젝트

AGV 개발 당시 RVIZ로 디버깅 및 시나리오 제어를 하기에는 너무 많은 시간이 소모되어 내부 디버깅 및 시나리오 테스트 용으로 진행한 프로젝트였다.

세부 내용

  • 기간 : 2018.09 ~ 2018.12

  • 개발 언어 : C++ ( Qt 4.,7 )

  • 개발 환경 및 사용 라이브러리

    • Ubuntu 16.04

    • ROS kinectic

담당 파트

AGV 시나리오 관리 모듈

XML을 사용하여 AGV의 Waypoint, Scenario 를 관리하는 모듈을 개발하였다. AGV의 현재 위치를 저장하기 위해 ROS Service를 이용하여 구현하였다.

AGV Navigation 모듈

시나리오 모듈에서 생성한 Waypoint 기반 Scenario 및 ROS Action Server를 이용하여 AGV의 목적지 설정 및 실시간 Viewing 기능을 구현하였다. SLAM 단계에서 나온 Map을 바탕으로 현재 로봇의 위치 및 Navigation 중 실시간으로 위치 업데이트 기능을 구현하였다.

어려웠던 점

ROS에 대한 전반적인 이해 부족

현 시점(21.09)에서 생각해보면 ROS는 하나의 통신 프로토콜이라 생각한다. Ros Master에 Topic, Message 등을 던지면 Master에서 각 Node들로 Topic, Message를 던져주며 각 Node에서는 Master에서 받은 메세지 기반으로 동작하게 되어있다. 하지만 당시 프로젝트 수행 당시 ROS에 대한 이해 없이 어떻게든 기능만 구현하자는 생각으로 Application을 개발했던 것 같다.

정리

Qt framework 을 사용한 두번째 프로젝트라 첫 프로젝트 만큼의 어려움과 난이도가 있다고는 생각하지 않았다. 프로젝트의 요구사항을 분석하여 UI 인터페이스를 설계하고 구현 경험을 쌓을 수 있었으며 프로그램 설계 능력 미숙 및 유지보수를 고려하지 않은 구현 등으로 Application 설계 능력 및 디자인 패턴에 관심이 생기게 된 프로젝트였다.

프로젝트명

EFEM Revision

소속/기관명

티로보틱스

프로젝트 기간

2018.06. ~ 2019.02.

프로젝트 내용

개요

고객사의 요구사항 변경으로 인한 기존 Application Revision 프로젝트

반도체 포토 공정에서 사용하는 웨이퍼 노광장비와 연동하여 Wafer Align 장비의 하드웨어 및 제어 어플리케이션을 제작하여 납품한 프로젝트였다.

세부 내용

  • 기간 : 2018.06 ~ 2019.02

  • 개발 언어 : C++ ( Qt 4.,7 )

  • 개발 환경 및 사용 라이브러리

    • Window 7

    • Visual Studio 2015

    • Univer Robot5 CB Series

    • opencv2

    • SMARTEK Camera SDK

    • FAS_EziMOTIONPlusR

담당 파트

Universal Robot 시퀀스 변경 및 티칭

로봇 동작 별 모듈화 및 하드웨어 변경으로 인한 로봇 티칭을 진행했다.

기존 프로젝트에서 하나의 명령어로 모든 동작을 진행했기 때문에 노광장비로 Wafer 이송 후 로봇은 대기할 수 밖에 없었고 이는 택 타임 증가라는 문제점을 지적받았다.

이를 해결하기 위해 로봇의 각 동작을 모듈화 시켰고 Foup에서 Wafer를 꺼낸 후 Align을 맞추고 노광장비에 Wafer 이송 후 다시 Foup에서 Wafer를 꺼내 Align작업을 하게 되어 택 타임을 Wafer 한 장 당 1'40'' 의 택타임을 55'' 까지 줄일 수 있었다.

Alignment 모듈 통합

Foup에서 Wafer를 꺼낸 후 Align을 위한 서보모터와 Vision 의 동작에 변경이 생겨 팀 내 선임 개발자께서 개발한 Alignment 모듈을 기존 Application에 통합하였다.

Wafer 추적기능 추가

하나씩 사용하던 Foup을 두 개 병렬로 사용하게 되면서 Wafer 추적기능이 필요하게 되어 Wafer 추적 및 Viewing기능을 개발했다.

장비 동작 시 장비 내부의 어떤 모듈에 몇 번 Foup의 몇 번 Wafer가 있는지 UI 변경 및 노광 장비와의 통신 프로토콜 설계를 진행하였다.

어려웠던 점

첫 프로젝트

당시 C++는 대학교 교양수업에서 C언어로 간단한 콘솔 어플리케이션만 개발해본 나에게 있어 완전히 새로운 언어였다. 사내에서 사용하는 C++ 및 Qt 프레임워크에 대한 사용 경험은 전무했다.

입사 후 6개월간 C++ 스터디를 진행하며 주말내내 출근하여 Qt프레임워크 및 Universal Robot에 대해 서적 과 교육자료 등으로 개인 역량을 키워나갔고 첫 프로젝트를 무사히 끝낼 수 있었다.

정리

입사 후 맡았던 첫 프로젝트라 아쉬움이 많이 남는 프로젝트였다. 가장 큰 세 가지를 꼽아 보자면 다음과 같다.

프로젝트 코드 구조 변경

다른 클래스와 공유하는 데이터를 다루는 모델 부분과 View의 이벤트를 관리하는 Controller 부분이 하나의 클래스 안에 구현되어 있어 유지보수가 어려웠다. 만약 이 시점(21.09)에서 이 프로젝트를 맡았다면 각 부분 별 모듈화를 위해 UI쪽 이벤트 처리부분과 데이터를 다루는 부분, 장비 모듈들을 각각 분리했을 것 같다.

쓰레드 관리 영역

너무 많은 쓰레드를 생성하여 사용하고 있었다. 쓰레드풀을 사용하여 각 쓰레드의 관리를 맡기는 방식이 아닌 Log, Device Init, Start, Reset 등 대부분의 기능을 쓰레드를 선언하여 쓰레드 내부에서 무한루프를 돌리며 flag로 관리하고 있었고 프로그램 종료 및 재시작 시 쓰레드 종료 처리가 제대로 되지 않아 백그라운드에서 프로그램이 실행됐던 적이 있었다. 다행히 Close이벤트를 받아 모든 쓰레드를 종료하는 방식으로 처리했지만 Application 개발 시점에서 App flow 도 파악하지 못한 채 유지보수를 시작하면 안된다는 생각을 가지게 한 프로젝트였다.

UI 개발 역량의 한계

Wafer 추적 기능을 넣는 중 장비의 각 부분을 Viewing 하고 그 위에 Wafer를 그려달라는 요청이 있었다. 프로젝트 수행 당시 화면에 UI를 그리고 실시간으로 Wafer의 이동위치를 그리기에는 역량이 부족하여 jpg, png 등 리소스를 활용하여 Viewing을 구현했었다.

댓글