한쪽 API에서만 되는 센서가 있어서 프로그램을 둘로 나누게 됐다. 로봇 쪽이 센서를 읽고 컴퓨터 쪽이 계산한다.
Table of contents
Open Table of contents
프로그램을 둘로 나눴다
leJOS 의 NXTConnector 가 Bluetooth 나 USB 로 붙여 주고 getInputStream() 과 getOutputStream() 을 준다. 연결 자체는 라이브러리가 해 준다. 붙여 놓고 나니 다음 문제가 나왔다. 스트림이 열렸을 뿐이고 무엇을 어떤 모양으로 보낼지는 내가 정해야 한다. 이미 정의된 LCP 가 있지만 그건 센서가 안 되는 쪽 경로였다.
말로 하면 간단하다. 센서를 읽으라고 하고, 몇 번 포트인지 알려 주고, 결과로 색 값 셋을 돌려받으면 된다. 그런데 그걸 어떻게 담아 보낼지가 안 떠올랐다.
가장 쉬워 보이는 방법부터 했다. 문자열에 쉼표로 구분해 넣고 DataOutputStream 으로 감싸 흘려보냈다.
"READ,3"
"RESULT,200,50,30"
막힐 때마다 칸을 붙였다
간단한 명령은 이걸로 됐다. 종류가 늘면서 걸리기 시작했다. 읽기와 쓰기와 모터 제어와 상태 조회가 인자 개수가 전부 다르다. readUTF() 한 번으로 다 받을 수가 없었다. 받는 쪽에서 몇 개가 올지 모른다.
그래서 길이를 앞에 붙였다. 받는 쪽이 DataInputStream 에서 얼마나 읽을지를 알게 된다. 그런데 길이만으로는 부족했다. 길이가 여덟이라는 것만으로는 읽기 명령인지 쓰기 명령인지 알 수 없어서 명령 번호를 넣었다.
또 하나 걸린 것은 방향이었다. 같은 연결로 명령과 응답이 양쪽으로 오간다. 받은 것이 명령인지 응답인지 구분할 표시가 하나 더 필요했다. 인자가 숫자일 때도 있고 문자일 때도 있어서 해석 방법을 알려 줄 타입 표시도 넣었다.
마지막에 붙은 것이 패킷 번호다. 요청 둘을 연달아 보내 놓으면 응답이 왔을 때 어느 요청의 것인지 알 수 없었다. 요청을 하나씩만 보내고 응답을 기다리면 번호가 필요 없지만, 그러면 기다리는 동안 아무것도 못 해서 느리다. 번호를 붙이는 쪽을 골랐다.
패킷 번호 | 길이 | 명령 번호 | 인자 타입 | 인자 값 | 응답 여부
여섯 칸이 됐는데 처음부터 설계한 것이 아니라 하나씩 늘어난 것이다. 칸마다 그걸 안 넣어서 막혔던 자리가 있다.
네 곳이 같은 형식을 알아야 했다
형식이 정해지니 양쪽에 보내는 부분과 받는 부분이 각각 필요했다. 둘 다 Java 인데 로봇 쪽은 NXJ 판이라 쓸 수 있는 클래스가 적었다. 컴퓨터 쪽에 둘, 로봇 쪽에 둘이라 네 조각이다. 네 곳이 전부 같은 형식을 알아야 하고 한 곳만 고치면 안 맞는다.
명령 번호 같은 것을 한 곳에 모아 static final 상수로 뺐다. 양쪽이 같은 정의를 보게 하려는 것이다. 다만 로봇 쪽과 컴퓨터 쪽이 다른 프로젝트라 그 .java 를 복사해야 했다. 고칠 때 둘 다 고치는 것을 잊으면 어긋난다. 이건 못 풀었다.
나중에 붙은 이름
다 만들고 나서 찾아보니 이런 것에 이름이 있었다. 메시지 프로토콜이라고 부르고 이미 쓰이는 형식들이 있다. LCP 도 그중 하나였다.
기존 형식을 먼저 봤으면 처음부터 여섯 칸으로 시작했을 것 같다. 다만 그랬으면 각 칸이 왜 필요한지는 몰랐을 것이다. 따라 만들면 칸은 맞는데 이유를 모르고, 막혀서 붙이면 느린 대신 이유를 안다. 어느 쪽이 나은지는 아직 모르겠다.
정리
- 한쪽에서만 되는 제약 때문에 프로그램을 둘로 나눴다
NXTConnector는 스트림까지만 주고 그 위에 얹을 것은 내가 정한다LCP라는 기성 프로토콜이 있었지만 그 경로로는 센서가 안 됐다- 나누고 나니 무엇을 어떤 모양으로 보낼지를 정해야 했다
DataOutputStream에 문자열로 시작해서 막힐 때마다 칸을 하나씩 붙였다- 길이와 명령 번호와 인자 타입과 응답 여부와 패킷 번호가 각각 이유가 있었다
- 요청을 하나씩 보내면 번호가 필요 없는데 느려서 번호를 붙이는 쪽을 골랐다
- 형식을 아는 곳이 넷이 돼서 명령 번호를
static final로 모았다 - 프로젝트가 달라
.java를 복사해야 했고 그건 못 풀었다 - 다 만들고 찾아보니 이미 이름이 붙어 있는 개념이었다