HAPTIX Tactor Glove - modulabs/gazebo-tutorial GitHub Wiki
์ด ํํ ๋ฆฌ์ผ์์๋ HAPTIX ์๋ฎฌ๋ ์ดํฐ์ ์ผ์ ๋ฐ์ดํฐ๋ฅผ ์ค์ ์ด๊ฐ ํผ๋๋ฐฑ์ผ๋ก ๋ณํํ๋ ๋ฐ ํ์ํ "tactor glove"์ ๋ง๋๋ ๋ฐฉ๋ฒ์ ์๋ ค์ค๋ค.
- 5 Lilypad Vibe Boards
- 1 Teensy USB Board
- 1 Mini-B USB cable (available from Amazon, Radioshack, etc.)
- Wires (we used 30 gauge teflon)
- Soldering iron
- 1 glove, preferably made of a thin spandex material
- Needle and thread (or a sewing machine)
Gazebo์ handsim ํจํค์ง๊ฐ์๋ Linux ์ปดํจํฐ๊ฐ ํ์ํ๋ค. ์ค์น ๋ฐฉ๋ฒ์ ์ด ํํ ๋ฆฌ์ผ์ ์ฐธ๊ณ ํ๋ผ.
Teensy USB ๋ณด๋๋ฅผ ํ๋ก๊ทธ๋๋ฐํ๋ ค๋ฉด Arduino IDE ๋ฐ Arduino ์ฉ Teensyduino ์ ๋์จ์ ์ค์นํด์ผํ๋ค.
์ฅ๊ฐ๊ณผ ํต์ ํ๋ ์ปดํจํฐ๋๋ Linux(์ฐ๋ถํฌ๊ฐ ๋ฐ๋์ง ํจ)๋ฅผ ์คํํ๊ณ haptix-comm ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ค์น๋์ด ์์ด์ผํ๋ค (์ค์น ๋ฐฉ๋ฒ์ ์ฌ๊ธฐ ์ฐธ์กฐ). ๊ฐ์ ๋ณด๋ฅผ๋ฅผ ์คํํ๋ ๋์ผํ ์ปดํจํฐ์ผ ์ ์์ง๋ง ๋ฐ๋์ ๊ทธ๋ด ํ์๋ ์๋ค.
์ด๊ฒ์ ์ด ํํ ๋ฆฌ์ผ์์ ๊ฐ์ฅ ์ด๋ ค์ด ๋ถ๋ถ์ด๋ฉฐ, ๊ฐ์ฅ ์ฌ๋ฏธ์์ ๊ฒ์ด๋ค.
tactor glove์ ๊ธฐ๋ณธ ์์ด๋์ด๋ ์ฅ๊ฐ์ ๊ฐ ์๊ฐ๋ฝ์ 5 ๊ฐ์ Lilypad ๋ณด๋๋ฅผ ๋ถ์ฐฉํ๋ ๊ฒ์ด๋ค. ๊ฐ ์๊ฐ๋ฝ์ Lilypad๋ฅผ ๋ฐฐ์นํ๊ณ , ๋ณด๋์ ๋ถ์ฐฉํ๋ ๋ฐฉ๋ฒ๊ณผ ์ฅ๊ฐ์ ์ข ๋ฅ (๋ชจ๋ ์๊ฐ๋ฝ์ด ์๋ vs. ์๊ฐ๋ฝ์ด์๋)๋ ๋ชจ๋ ์ฌ์ฉ์ ๋ง์์ด์ด๋ค. ์ค์ ๋ก, ์ฅ๊ฐ ๋์ ์ ์์ฅ์ ์ฌ์ฉํ ์ ์๋ค (ํนํ, ์ค์ ์ธ๊ณต ํ์ ์ค๋นํ๋ ์ฌ๋์ ์ํด ํ ํฑ ํผ๋๋ฐฑ ์์คํ ์ ์ค๊ณํ๋ ๊ฒฝ์ฐ). Lilypads์ ํ๋ธ ์ญํ ์ํ๊ณ ์ปดํจํฐ์ ์ฐ๊ฒฐํ๋ USB ๋ณด๋๋ฅผ ์ด๋์ ๋ ๊ฒ์ธ์ง ์๊ฐํ๊ณ ์ถ์ ๊ฒ์ด๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฐ๋์งํ๋ ๋ฒ์ ๋ชจ๋ฅธ๋ค๋ฉด, ๊ธ๋ฃจ๊ฑด์ผ๋ก..
์ฐ๋ฆฌ๋ ๋ชจ๋ ์๊ฐ๋ฝ์ด ์๋ ๊ธ๋ฌ๋ธ๋ก ์์ํ์ฌ Lilypads๋ฅผ ๋ฃ๊ธฐ ์ํด ๊ฐ ์๊ฐ๋ฝ์ ์๋์ชฝ 1/3์ ์ฃผ๋จธ๋๋ฅผ ๊ฟฐ๋งค์๋ค. ์ฃผ๋จธ๋๋ Lilypads๊ฐ ๋จ์ด์ง ์ํ์ด์๋ ์ง๋ฌผ์ ๋ํด ์ถฉ๋ถํ์๋ค. USB ๋ณด๋๋ฅผ ์๋ฑ์ ์ฃผ๋จธ๋์ ๋ฃ๊ณ USB ์ผ์ด๋ธ์ ์ฅ๊ฐ ๋ฐ๋ฅ ๊ทผ์ฒ์ ์์ ๊ตฌ๋ฉ์ ๋ฃ์๋ค. ๊ฐ ์์ ์ ์ ์ ํจ๊ป ๋คํ์ด ๊ผฌ์ด๋ ๊ฒ์ ์ต์ํํ๊ธฐ ์ํด ๋ชจ๋ ์ผ์ด๋ธ์ ์๋ฑ์ ๋ฌถ์๋ค.

๊ฐ Lilypad์ ๋ํด ๋ ๊ฐ์ ์ ์ ์ ์ธก์ ํ๋ค. ์ ์ ์ ๊ธธ์ด๋ ๋ชจํฐ์ ์๊ฐ๋ฝ ๋ฐฐ์น์ ๋ณด๋ ๋ฐฐ์น์ ๋ฐ๋ผ ๋ค๋ฅด๋ค. ์ ์ด๋ 8 ์ธ์น(์ฝ๊ฐ ์ํ์ง ์๊ฒ)๋ฅผ ์ถ์ฒํ๋ค.
๊ฐ Lilypad์ ๋ํด ์๊ทน(-)๋จ์๋ฅผ Teensy ๋ณด๋์ GND ํ์ ์ฐ๊ฒฐํ๊ณ ์(+)๋จ์๋ฅผ ์ํ๋ ๋ฒํธ์ ๊ณ ์ ํ ํ์ ์ฐ๊ฒฐํ๋ค. ์ฌ๊ธฐ์์๋ 4, 9, 10, 12 ๋ฐ 14 ๋ฒ ํ์ ์ ํํ์๋ค. ๋ค์ ์น์
์์ Arduino ์ฝ๋์ ์ํฅ์ ๋ฏธ์น๋ฏ๋ก ์ฌ์ฉํ๋ ํ์ ๋ฉ๋ชจํด๋๋ค.
Mini-USB ์ผ์ด๋ธ์ Teensy ๋ณด๋์ ํฌํธ์ ์ฐ๊ฒฐํ๋ค.
Optional : Lilypad ๋ณด๋์ USB ๋ณด๋๋ฅผ ์์ถ๋ฉ์ผ๋ก ๋ฎ์๋ค. ์ด๊ฒ์ ์ฌ๋ฌ ๊ฐ์ง ์ฉ๋๋ก ์ฌ์ฉ๋๋ค. ์์ด์ด์์ ์คํธ๋ ์ค๋ฅผ ๋ฐ์ผ๋ฉด์ ์ง๋ฌผ์์ ๋ฐ์ํ๋ ์ ์ ๊ธฐ ๊ฐ์ญ์ ๋ฐฉ์งํ๋ฉฐ, ๋๊ตฐ๊ฐ๊ฐ ๋ง์ดํด๋๋ฅผ ์ฌ๋์ค๋ฝ๊ฒ ๋ง๋ค์ด์ง ์ฅ๊ฐ์ผ๋ก ์์๋ด๋ ๊ฒฝ์ฐ์ ๋๋นํ์ฌ ๋ณดํธ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
์ด์ ๋ชจ๋ ๊ฒ์ด ๋ฉ๋๋์ด ์ฐ๊ฒฐ๋์์ผ๋ฏ๋ก Lilypads buzz๋ฅผ ๋ง๋ค ํ์ด๋ฐ์ด๋ค.
Arduino IDE๋ฅผ ์ด๊ณ ์๋ก์ด ์ค์ผ์น๋ฅผ ์์ํ๋ค. '๋๊ตฌ' ๋๋กญ ๋ค์ด ๋ฉ๋ด๋ฅผ ํด๋ฆญํ๊ณ 'USB ์ ํ: "์ง๋ ฌ"'์ ์ ํํ๋ค.
Arduino ์ค์ผ์น ์ฝ๋๋ฅผ ์ฌ๊ธฐ์์ ๋ค์ด๋ก๋ ๋ฐ์ Arduino IDE์ ๋ณต์ฌํ๋ค.
Arduino ์ค์ผ์น๋ ๋ฌด์์ ํ ๊น? USB ๋ณด๋๊ฐ Linux ์ปดํจํฐ์ ์ฐ๊ฒฐ๋๋ฉด ACM ์ฅ์น (์: "/dev/ttyACM0")๊ฐ ์์ฑ๋๋ค. ํด๋น ์ฅ์น์ ๊ธฐ๋ก ๋ ๋ฌธ์๋ฅผ ์์ ํ๋ค. '1'์์ '5' ๋ฌธ์๊ฐ ์ฅ์น์ ์ฐ์ฌ์ง๋ฉด ํด๋น ๋ชจํฐ๊ฐ 100 ๋ฐ๋ฆฌ ์ด ๋์ ์์๊ฑฐ๋ฆฌ๋ฉฐ(buzz) ์ธ๋ฆฐ๋ค.
์ ์ ์ค์ ์ด๋ ๊ธฐํ ํ๊ฒฝ ์ค์ ์ ๋ฐ๋ผ ์ด ์ฝ๋๋ฅผ ์ฌ์ฉ์๊ฐ ์ ์ ํ ์ ์๋ค.
#define NUM_MOTORS 5๋ชจํฐ๊ฐ 5๊ฐ ์ด์์ธ ๊ฒฝ์ฐ ์ด ์ซ์๋ฅผ ๋ณ๊ฒฝํ์ฌ ์ผ์น์ํจ๋ค.
#define MOTOR_RUN_TIME 100์ด ์ ์ ํ๋์ ๋ชจํฐ 'ํด๋ฆญ' ๊ธธ์ด๋ฅผ ๋ฐ๋ฆฌ์ด ๋จ์๋ก ์ ์ํ๋ค.
int motors[NUM_MOTORS] = {4, 9, 10, 12, 14};์ด ์ซ์๊ฐ ์ด์ ์น์ ์์ Lilypad ๋ณด๋๋ฅผ ์ฐ๊ฒฐํ๊ธฐ ์ํด ์ ํํ ํ๊ณผ ์ผ์นํ๋์ง ํ์ธํ๋ค.
unsigned long t_motor_start[NUM_MOTORS] = {0, 0, 0, 0, 0};๋ชจํฐ ์๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒฝ์ฐ ์ด ๋ฐฐ์ด์์ 0์ ์๋ฅผ ๋ณ๊ฒฝํ๋ค.
if (b >= '1' && b <= '5')
{
int motor = b - '1';
t_motor_start[motor] = millis();
analogWrite(motors[motor], MOTOR_PWM);
}์ด ์น์ ์ ์์ ํ์ฌ ๋ชจํฐ์ ๋ฒ์ฆ๋ฅผ ๋ง๋๋ ๋ฌธ์๋ฅผ ๋ณ๊ฒฝํ ์ ์๋ค. ์๋ฅผ ๋ค์ด 1-5 ๋์ 'a', 'b', 'c'...๋ฅผ ์ฌ์ฉํ ์ ์๋ค. ๋ํ ๋ชจํฐ์ ์๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒฝ์ฐ 'if'๋ฌธ์์ ํ๊ณ๊ฐ์ ๋ณ๊ฒฝํด์ผ ํ๋ค.
ํ๋ก์ ํธ๋ฅผ ๋น๋ํ๊ณ Teensy ๋ถํธ ๋ก๋๋ฅผ ์ฌ์ฉํ์ฌ ์ค์ผ์น๋ฅผ ๋ณด๋์ ๋ก๋ํ๋ค.
์ ์ ์ฅ์น์ ์ํํธ์จ์ด๊ฐ picocom๋ฅผ ์ฌ์ฉํ์ฌ ์๋ํ๋์ง๋ ์ฝ๊ฒ ํ ์คํธํ ์ ์๋ค.
ํฐ๋ฏธ๋์์ picocom์ ์คํํ๋ค.
sudo apt-get install picocom
tactor glove๋ฅผ ์ปดํจํฐ USB ํฌํธ์ ์ฝ์ ํ๊ณ ์คํํ๋ค.
picocom /dev/ttyACM0
๋ชจํฐ buzz ์์ฑ์ ์ํด ์ซ์ ํค 1-5 (๋๋ ์ด์ ๋จ๊ณ์์ ์ ํํ ๋ฌธ์์ ํด๋นํ๋ ํค)๋ฅผ ๋๋ฅธ๋ค. CTRL-a CTRL-q๋ฅผ ๋๋ฌ ์ข ๋ฃํ๋ค.
/dev/ttyACM0์ด ์ด๋ฆฌ์ง ์๊ฑฐ๋ ๋ฌธ์๋ฅผ ๋ณด๋ด์ง ์์ผ๋ฉด ls /dev๋ฅผ ์ฌ์ฉํ์ฌ ๋ค๋ฅธ ACM ์ฅ์น๋ฅผ ์ฌ์ฉํ ์ ์๋์ง ํ์ธํ๊ณ ๋ค๋ฅธ ์ฅ์น๋ก ํ๋ก์ธ์ค๋ฅผ ์๋ํ๋ค.
picocom์ ๋ฃจํธ (sudo picocom)๋ก ์คํํด์ผ ํ ์๋ ์๋ค. sudo๋ฅผ ํ์ง ์๊ณ ์ฅ์น๋ฅผ ์ด๋ ค๋ฉด ์ฌ์ฉ์ ์ด๋ฆ์ plugdev ๋ฐ dialout ๊ทธ๋ฃน์ ์ถ๊ฐํด์ผํ๋ค.
sudo usermod -a -G plugdev <username>
sudo usermod -a -G dialout <username>
๋ช ๋ น์ -a๋ฅผ ํฌํจ์ํจ๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ๊ณ์ ์ด sudo ์ก์ธ์ค ๊ถํ์ ์์ ์ ์๋ค!
์ ์ ์ฅ์น์ Arduino ์ค์ผ์น๊ฐ ์๋ํ๋ ๊ฒ์ ํ์ธํ ํ์๋ ์ฒซ ๋ฒ์งธ ๋จ๊ณ์์ ๋ชจํฐ๋ฅผ ์ฅ๊ฐ์ ์ฐ๊ฒฐํ๊ธฐ ์ํด ๋ง๋ ๊ณํ์ ์คํํ๋ค. ๊ฐ ์๊ฐ๋ฝ์ ๋ชจํฐ์ ์ด๋ค ๋ฌธ์๊ฐ buzz๋ฅผ ๋ง๋๋์ง ํ์ธํ๋ค. ์ฐธ๊ณ ๋ก, ์ฌ๊ธฐ์ ์ฌ์ฉํ ๋งตํ์ ๋ค์๊ณผ ๊ฐ๋ค: Finger Board PinCharacter Index 4 1 Middle 9 2 Ring 10 3 Little 12 4 Thumb 14 5
์๋ฎฌ๋ ์ด์ ์์ ์ ์ด ์ผ์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ ์ด๋ฅผ ๋ชจํฐ ํด๋ฆญ์ผ๋ก ๋ณํํ๋ haptix-comm ํด๋ผ์ด์ธํธ๋ฅผ ์์ฑํ๋ค.
์ด ํ๋ก์ ํธ์ ๋ํ ์ฅ๊ฐ ์์ค ์ฝ๋์ CMakeLists.txt๋ฅผ ๋ค์ด๋ก๋ ํ๋ค. ์ด ํ์ผ์ ์ ํด๋(์: tactors) ๋ณต์ฌํ๋ค.
์ด c++ ์ฝ๋๋ /dev/ttyACM0์ ์ด๊ณ hx_getdeviceinfo๋ฅผ ํธ์ถํ์ฌ haptix-comm ํด๋ผ์ด์ธํธ๋ฅผ ์ด๊ธฐํ ํ๋ค. Lilypads์์ ๋ชจํฐ buzzes๋ฅผ ํ์ฑํํ๋ ๋ฌธ์์ ํด๋น ์๊ฐ๋ฝ์ ๋ํ ์ผ์ ์ ์ด ์์ธ ๊ฐ์ ๋งคํ์ ์ค์ ํ๋ค. 10Hz๋ก ์คํ๋๋ ์
๋ฐ์ดํธ ๋ฃจํ์์, haptix-comm์์ ์ผ์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ ์ ์ด ์ผ์ ์ค ํ๋๊ฐ ์ผ์ ํ ์ต์๊ฐ์ ์ด๊ณผํ๋ฉด ํด๋น ๋ฌธ์๋ฅผ /dev/ttyACM0์ ์๋๋ค.
์ด ์์ ์ ๋ค๋ฅธ ์ ์ ์ฅ์น ์ค์ ์ด ์๋ ๊ฒฝ์ฐ ์ฝ๋์ ์ผ๋ถ๋ถ์ ์ฌ์ฉ์๊ฐ ์ง์ ํด์ผ ํ ์๋ ์๋ค.
const unsigned int sleeptime_us = 10000;
const float minContactForce = 0;sleeptime_us์ ์๋ฎฌ๋ ์ดํฐ์ ์
๋ฐ์ดํธ ์๋๋ฅผ ์ ์ดํ๋ค. ๊ธฐ๋ณธ๊ฐ์ 10000 ๋ง์ดํฌ๋ก์ด ๋๋ 10 ๋ฐ๋ฆฌ์ด์ด๋ค. minContactForce๋ ์ ์์ผ์๊ฐ ํด๋น ๋ชจํฐ ํด๋ฆญ์ ๋ง๋ค๊ธฐ ์ํ ์ต์ ํ์ด๋ค. ์ฅ๊ฐ์ ์ ์ด์ ๋ ๋ฏผ๊ฐํ๊ฒ ๋ง๋ค๋ ค๋ฉด ์ด ๊ฐ์ ํค์ฐ๋ฉด ๋๋ค.
int fd = open("/dev/ttyACM0", O_WRONLY);
if (fd < 0)
{
perror("Failed to open /dev/ttyACM0");
return -1;
}/dev/ttyACM0์ ์ด๋ฏธ ACM ์ฅ์น๊ฐ ์ฐ๊ฒฐ๋์ด์๋ ๊ฒฝ์ฐ ์ฅ๊ฐ์ ๋ค๋ฅธ ์ฅ์น ํ์ผ (์:/dev/ttyACM1)์ ์ฐ๊ฒฐํ ์ ์๋ค. ์ฅ๊ฐ์ด ๋ค๋ฅธ ์ฅ์น ํ์ผ์์ ๊ณ์ ์ด๋ฆฌ๋ ๊ฒฝ์ฐ ํด๋น ์ฅ์น๋ฅผ ๊ฐ์ ธ ์ค๊ธฐ ์ํด ์ด๊ธฐ ๋ช
๋ น์ ๋ณ๊ฒฝํ๋ค.
for (unsigned int i = 0; i < deviceInfo.ncontactsensor; i++)
{
// Uninitialized
sensorMotorIndexMapping[i] = '0';
}
for (unsigned int i = 3; i <= 6; i++)
{
// Index
sensorMotorIndexMapping[i] = '1';
}
for (unsigned int i = 11; i <= 14; i++)
{
// Middle
sensorMotorIndexMapping[i] = '2';
}
for (unsigned int i = 17; i <= 20; i++)
{
// Ring
sensorMotorIndexMapping[i] = '3';
}
for (unsigned int i = 7; i <= 9; i++)
{
// Little
sensorMotorIndexMapping[i] = '4';
}
for (unsigned int i = 21; i <= 23; i++)
{
// Thumb
sensorMotorIndexMapping[i] = '5';
}์ฝ๋์์ด ๋ถ๋ถ์ MPL ํ์ ๊ฐ ์๊ฐ๋ฝ์์๋ ์ ์ด ์ผ์์ ์์ธ์ /dev/ttyACM0์ ๊ธฐ๋ก ํ ๋ ๋ชจํฐ buzz๋ฅผ ๋ง๋ค ๋ฌธ์๋ก ๋งคํํฉ๋๋ค. Arduino ์ค์ผ์น์ ๋ฌธ์๋ฅผ ๋ณ๊ฒฝ ํ ๊ฒฝ์ฐ ๋งต ํญ๋ชฉ์ ๊ฐ์ ๋ณ๊ฒฝํ๋ค.
if (j <= '5' && j >= '1')๋ชจํฐ์ ๋งคํ๋๋ ๋ฌธ์์ ๋ฒ์๊ฐ ๋ค๋ฅธ ๊ฒฝ์ฐ ์ด ๋ฒ์๋ฅผ ๋ณ๊ฒฝํด์ผ ํ ์๋ ์๋ค.
ํ์ํ ์์ ์ ํ ํ ์ฝ๋๊ฐ ์๋ ํด๋์์ ๋ค์ ๋ช ๋ น์ ์คํํ๋ค:
mkdir build;
cd build;
cmake ..;
make
๋ณ๋์ ์ฐฝ์์ Gazebo HAPTIX ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์คํํ๋ค.
gazebo worlds/arat.worlds
๊ทธ๋ฆฌ๊ณ C++ ์ฝ๋๊ฐ์๋ ํด๋์์ tactors๋ฅผ ์คํํ๋ค. ์ฅ๊ฐ์ ๋ผ๊ณ ์๋ฎฌ๋ ์ดํฐ์์ ๋ฌผ๊ฑด์ ์ง๋๋ค.



