Skip to content

Deamonio/DiSRHiT

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

66 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿค– DiSRHiT

Disaster Site Rescue Hand Tracking Robot

์žฌ๋‚œ ํ˜„์žฅ์„ ์œ„ํ•œ ์†๋™์ž‘ ์ถ”์  ๊ตฌ์กฐ ๋กœ๋ด‡

Python Raspberry Pi MediaPipe

GitHub Stars GitHub Forks

My Favorite Production โญ


๐ŸŽฅ Demo Video

DiSRHiT Demo

โ–ถ๏ธ ํด๋ฆญํ•˜์—ฌ ์‹ค์ œ ์ž‘๋™ ์˜์ƒ ๋ณด๊ธฐ

์†๋™์ž‘์œผ๋กœ ๋กœ๋ด‡ ํŒ”์„ ์‹ค์‹œ๊ฐ„ ์ œ์–ดํ•˜๋Š” DiSRHiT


๐Ÿ“‹ ๋ชฉ์ฐจ


๐ŸŽฏ ํ”„๋กœ์ ํŠธ ์†Œ๊ฐœ

**DiSRHiT (Disaster Site Rescue Hand Tracking Robot)**๋Š” ์žฌ๋‚œ ํ˜„์žฅ์—์„œ ๊ตฌ์กฐ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์†๋™์ž‘ ์ œ์–ด ๋กœ๋ด‡ ์‹œ์Šคํ…œ์ž…๋‹ˆ๋‹ค.

๐Ÿ’ก ํ”„๋กœ์ ํŠธ ๋ฐฐ๊ฒฝ

์žฌ๋‚œ ํ˜„์žฅ์—์„œ๋Š” 2์ฐจ ๋ถ•๊ดด ์œ„ํ—˜์œผ๋กœ ์ธํ•ด ๊ตฌ์กฐ๋Œ€์›์ด ์ง์ ‘ ์ ‘๊ทผํ•˜๊ธฐ ์–ด๋ ค์šด ์ƒํ™ฉ์ด ๋งŽ์Šต๋‹ˆ๋‹ค.
DiSRHiT๋Š” ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์›๊ฒฉ์œผ๋กœ ์†๋™์ž‘๋งŒ์œผ๋กœ ๋กœ๋ด‡์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” ์‹œ์Šคํ…œ์„ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

๐ŸŒŸ ํŠน์ง•

  • โœ… ์ง๊ด€์  ์ œ์–ด: ์†๊ฐ€๋ฝ ๊ฐ๋„๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋กœ๋ด‡์— ์ „๋‹ฌ
  • โœ… ๋ฌด์„  ํ†ต์‹ : Socket ๊ธฐ๋ฐ˜ ์›๊ฒฉ ์ œ์–ด
  • โœ… ์ •๋ฐ€ ์ œ์–ด: 11๊ฐœ ์„œ๋ณด ๋ชจํ„ฐ ๋…๋ฆฝ ์ œ์–ด
  • โœ… ์‹ค์‹œ๊ฐ„ ์ฒ˜๋ฆฌ: MediaPipe ๊ธฐ๋ฐ˜ ๋น ๋ฅธ ์† ์ถ”์ 
  • โœ… ์•ˆ์ •์„ฑ: ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์œผ๋กœ ์•ˆ์ •์ ์ธ ๋ฐ์ดํ„ฐ ์ „์†ก

๐Ÿ—๏ธ ์‹œ์Šคํ…œ ์•„ํ‚คํ…์ฒ˜

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  AI Computer (์ œ์–ด ์ปดํ“จํ„ฐ)              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚  โ”‚  ์›น์บ                             โ”‚   โ”‚
โ”‚  โ”‚  โ†“                               โ”‚   โ”‚
โ”‚  โ”‚  MediaPipe ์† ์ถ”์               โ”‚   โ”‚
โ”‚  โ”‚  โ†“                               โ”‚   โ”‚
โ”‚  โ”‚  ์†๊ฐ€๋ฝ ๊ฐ๋„ ๊ณ„์‚ฐ (21 Landmarks)โ”‚   โ”‚
โ”‚  โ”‚  โ†“                               โ”‚   โ”‚
โ”‚  โ”‚  Socket Client (์†ก์‹ )           โ”‚   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
              โ†“ Socket (TCP/IP)
              โ†“ "action: 90: 90:90:..."
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Hand Robot (๋กœ๋ด‡ ํŒ”)                   โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚  โ”‚  Socket Server (์ˆ˜์‹ )           โ”‚   โ”‚
โ”‚  โ”‚  โ†“                               โ”‚   โ”‚
โ”‚  โ”‚  ๋ช…๋ น ํŒŒ์‹ฑ                       โ”‚   โ”‚
โ”‚  โ”‚  โ†“                               โ”‚   โ”‚
โ”‚  โ”‚  ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ๊ฐ๋„ ๋ถ„๋ฐฐ           โ”‚   โ”‚
โ”‚  โ”‚  โ†“                               โ”‚   โ”‚
โ”‚  โ”‚  PCA9685 PWM ๋“œ๋ผ์ด๋ฒ„           โ”‚   โ”‚
โ”‚  โ”‚  โ†“                               โ”‚   โ”‚
โ”‚  โ”‚  11๊ฐœ ์„œ๋ณด ๋ชจํ„ฐ ์ œ์–ด            โ”‚   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚  (Raspberry Pi)                         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โœจ ์ฃผ์š” ๊ธฐ๋Šฅ

1. ๐Ÿ–๏ธ MediaPipe ์† ์ถ”์ 

AI Computer (main_delay. py)

# MediaPipe๋กœ 21๊ฐœ ์† ๋žœ๋“œ๋งˆํฌ ์ถ”์ถœ
mp_hands = mp.solutions.hands

# ์†๊ฐ€๋ฝ ๊ฐ๋„ ๊ณ„์‚ฐ
joint_list = [
    [1,5,6],    # ์—„์ง€
    [0,9,10],   # ๊ฒ€์ง€
    [0,13,14],  # ์ค‘์ง€
    [0,17,18],  # ์•ฝ์ง€
    # ... ์ด 9๊ฐœ ๊ด€์ ˆ
]

# ๊ฐ๋„ ๊ณ„์‚ฐ (๋ฒกํ„ฐ ๊ธฐ๋ฐ˜)
radians = np.arctan2(c[1]-b[1], c[0]-b[0]) - \
          np.arctan2(a[1]-b[1], a[0]-b[0])
angle = np.abs(radians * 180.0 / np.pi)

ํŠน์ง•:

  • 21๊ฐœ ์† ๋žœ๋“œ๋งˆํฌ ์‹ค์‹œ๊ฐ„ ์ถ”์ 
  • 9๊ฐœ ์ฃผ์š” ๊ด€์ ˆ ๊ฐ๋„ ๊ณ„์‚ฐ
  • 180๋„ ๋ฒ”์œ„ ์ •๊ทœํ™”
  • ํ”„๋ ˆ์ž„๋‹น ์ฒ˜๋ฆฌ ์‹œ๊ฐ„: ~30ms

2. ๐Ÿ“ก Socket ํ†ต์‹ 

ํ”„๋กœํ† ์ฝœ ์„ค๊ณ„:

๋ช…๋ น ํฌ๋งท: 
"action:angle0:angle1:angle2:.. .:angle10"

์˜ˆ์‹œ:
"action:90:85:120:95:10: 15:20:25:45:50:60"
       โ””โ”€โ”ฌโ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
      ๋ช…๋ น์–ด        11๊ฐœ ์„œ๋ณด ๊ฐ๋„

AI Computer โ†’ Robot ํ†ต์‹ :

# ์†ก์‹  (AI Computer)
message = f"action:{': '.join(map(str, angles))}"
client_socket.send(message.encode())

# ์ˆ˜์‹  (Hand Robot)
data = client_socket.recv(1024)
command = data.decode().split(':')
# command[0] = 'action'
# command[1~11] = ๊ฐ ์„œ๋ณด ๊ฐ๋„

ํŠน์ง•:

  • TCP/IP ์†Œ์ผ“ ํ†ต์‹ 
  • ๋ฉ€ํ‹ฐ ํด๋ผ์ด์–ธํŠธ ์ง€์›
  • ์—๋Ÿฌ ํ•ธ๋“ค๋ง (ConnectionResetError)
  • ์ปฌ๋Ÿฌ ๋กœ๊ทธ ์ถœ๋ ฅ

3. โš™๏ธ ์„œ๋ณด ๋ชจํ„ฐ ์ œ์–ด

PCA9685 PWM ์ œ์–ด:

class Servo_Controller_Class:
    def __init__(self, Channel, ZeroOffset):
        self.mChannel = Channel
        self.m_ZeroOffset = ZeroOffset
        
        # PCA9685 ์ดˆ๊ธฐํ™” (I2C ์ฃผ์†Œ: 0x40)
        self.mPwm = Adafruit_PCA9685.PCA9685(address=0x40)
        self.mPwm.set_pwm_freq(60)  # 60Hz
    
    def SetPos(self, pos):
        # ๊ฐ๋„ โ†’ PWM ํŽ„์Šค ๋ณ€ํ™˜
        pulse = (650-150) * pos/180 + 150 + self.m_ZeroOffset
        self.mPwm.set_pwm(self. mChannel, 0, int(pulse))

PWM ๊ณ„์‚ฐ:

ํŽ„์Šค ๋ฒ”์œ„: 150 ~ 650 (4096 ๋‹จ๊ณ„ ์ค‘)
๊ฐ๋„ ๋ฒ”์œ„:   0ยฐ ~ 180ยฐ

๊ณต์‹: pulse = (650-150) ร— (angle/180) + 150 + offset

4. ๐Ÿงต ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ

๋™์‹œ ์ฒ˜๋ฆฌ:

# 11๊ฐœ ์„œ๋ณด๋ฅผ ๋™์‹œ์— ์—…๋ฐ์ดํŠธ
append_action_thread = []

for index in range(11):
    thread = threading.Thread(
        target=append_angle, 
        args=(index, command[index+1])
    )
    append_action_thread.append(thread)

# ๋ชจ๋“  ์Šค๋ ˆ๋“œ ๋™์‹œ ์‹œ์ž‘
for thread in append_action_thread:
    thread.start()

Lock์œผ๋กœ ๋™๊ธฐํ™”:

action_lock = [threading.Lock() for _ in range(11)]

def append_angle(index, pos):
    action_lock[index].acquire()
    action_range[index][0] = int(float(pos))
    action_lock[index]. release()

๐Ÿ”ง ๊ธฐ์ˆ  ์Šคํƒ

AI Computer (์ œ์–ด์ธก)

๊ธฐ์ˆ  ์šฉ๋„ ๋ฒ„์ „
Python ๋ฉ”์ธ ์–ธ์–ด 3.8+
MediaPipe ์† ์ถ”์  0.8.x
OpenCV ์˜์ƒ ์ฒ˜๋ฆฌ 4.5.x
NumPy ์ˆ˜์น˜ ๊ณ„์‚ฐ 1.21.x
Socket ๋„คํŠธ์›Œํฌ ํ†ต์‹  Built-in

Hand Robot (๋กœ๋ด‡์ธก)

๊ธฐ์ˆ  ์šฉ๋„ ๋ฒ„์ „
Raspberry Pi ๋ฉ”์ธ ๋ณด๋“œ 3B+ / 4
Python ์„œ๋ฒ„ ์–ธ์–ด 3.7+
Adafruit PCA9685 PWM ๋“œ๋ผ์ด๋ฒ„ I2C
RPi.GPIO GPIO ์ œ์–ด Latest
Socket ์„œ๋ฒ„ Built-in

๐Ÿ› ๏ธ ํ•˜๋“œ์›จ์–ด ๊ตฌ์„ฑ

์ „์ฒด BOM (Bill of Materials)

๋ถ€ํ’ˆ ์ˆ˜๋Ÿ‰ ์šฉ๋„
Raspberry Pi 3B+/4 1 ๋ฉ”์ธ ์ปจํŠธ๋กค๋Ÿฌ
PCA9685 16์ฑ„๋„ PWM 1 ์„œ๋ณด ์ œ์–ด
SG90 ์„œ๋ณด ๋ชจํ„ฐ 11 ์†๊ฐ€๋ฝ ๊ตฌ๋™
์›น์บ  1 ์† ์ถ”์  ์ž…๋ ฅ
5V ์ „์› ๊ณต๊ธ‰ 1 ์„œ๋ณด ์ „์›
์ ํผ ์™€์ด์–ด ๋‹ค์ˆ˜ ์—ฐ๊ฒฐ
๋ธŒ๋ ˆ๋“œ๋ณด๋“œ 1 ํ”„๋กœํ† ํƒ€์ž…

์„œ๋ณด ๋ชจํ„ฐ ๋ฐฐ์น˜

11๊ฐœ ์„œ๋ณด ๋ชจํ„ฐ: 
[0] ์—„์ง€ ๊ธฐ์ €๋ถ€
[1] ์—„์ง€ ์ฒซ์งธ ๋งˆ๋””
[2] ์—„์ง€ ๋๋งˆ๋””
[3] ๊ฒ€์ง€ ๊ธฐ์ €๋ถ€
[4] ๊ฒ€์ง€ ์ฒซ์งธ ๋งˆ๋””
[5] ๊ฒ€์ง€ ๋๋งˆ๋””
[6] ์ค‘์ง€ ์ฒซ์งธ ๋งˆ๋””
[7] ์•ฝ์ง€ ์ฒซ์งธ ๋งˆ๋””
[8] ์ƒˆ๋ผ ์ฒซ์งธ ๋งˆ๋””
[9] ์†๋ชฉ ํšŒ์ „
[10] ํŒ”๊ฟˆ์น˜

๐Ÿ“ฆ ์„ค์น˜ ๋ฐฉ๋ฒ•

AI Computer (์ œ์–ด ์ปดํ“จํ„ฐ)

1. ์ €์žฅ์†Œ ํด๋ก 

git clone https://github.com/Deamonio/DiSRHiT.git
cd DiSRHiT/AI_computer

2. ๊ฐ€์ƒํ™˜๊ฒฝ ์ƒ์„ฑ

python3 -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate

3. ์˜์กด์„ฑ ์„ค์น˜

pip install -r requirements.txt

requirements.txt:

mediapipe>=0.8.0
opencv-python>=4.5.0
numpy>=1.21.0
pygame>=2.0.0
gtts>=2.2.0

Hand Robot (Raspberry Pi)

1. SSH ์ ‘์†

ssh pi@<๋ผ์ฆˆ๋ฒ ๋ฆฌํŒŒ์ด_IP>

2. ์ €์žฅ์†Œ ํด๋ก 

git clone https://github.com/Deamonio/DiSRHiT.git
cd DiSRHiT/Hand_Robot

3. ์˜์กด์„ฑ ์„ค์น˜

pip3 install -r requirements.txt

requirements.txt:

RPi.GPIO>=0.7.0
adafruit-pca9685>=1.0.1

4. I2C ํ™œ์„ฑํ™”

sudo raspi-config
# Interfacing Options โ†’ I2C โ†’ Enable
sudo reboot

5. I2C ์ฃผ์†Œ ํ™•์ธ

sudo i2cdetect -y 1

์ถœ๋ ฅ ์˜ˆ์‹œ:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  โ† PCA9685

๐Ÿš€ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

1๏ธโƒฃ Hand Robot ์„œ๋ฒ„ ์‹œ์ž‘

# Raspberry Pi์—์„œ ์‹คํ–‰
cd DiSRHiT/Hand_Robot
python3 main. py

์ถœ๋ ฅ:

[Socket] Server started on 0.0.0.0:7672
[Socket] Waiting for connections...

IP ์ฃผ์†Œ ํ™•์ธ:

hostname -I
# ์˜ˆ: 192.168.1.100

2๏ธโƒฃ AI Computer ํด๋ผ์ด์–ธํŠธ ์‹คํ–‰

IP ์„ค์ •:

# AI_computer/main_delay.py
HOST = '192.168.1.100'  # Raspberry Pi IP
PORT = 7672

์‹คํ–‰:

cd DiSRHiT/AI_computer
python main_delay.py

์ถœ๋ ฅ:

[Socket] Connected to the Server
[Camera] Starting hand tracking...

3๏ธโƒฃ ์†๋™์ž‘ ์ œ์–ด

์ œ์–ด ๋ฐฉ๋ฒ•:

  1. ์›น์บ  ์•ž์— ์†์„ ํŽด๊ธฐ

    • MediaPipe๊ฐ€ 21๊ฐœ ๋žœ๋“œ๋งˆํฌ ์ธ์‹
    • ํ™”๋ฉด์— ์† ์Šค์ผˆ๋ ˆํ†ค ํ‘œ์‹œ
  2. ์†๊ฐ€๋ฝ ์›€์ง์ด๊ธฐ

    • ๊ฐ ์†๊ฐ€๋ฝ ๊ฐ๋„๊ฐ€ ์‹ค์‹œ๊ฐ„ ๊ณ„์‚ฐ
    • Socket์œผ๋กœ ๋กœ๋ด‡์— ์ „์†ก
  3. ๋กœ๋ด‡ ํŒ” ํ™•์ธ

    • ๋กœ๋ด‡ ์†๊ฐ€๋ฝ์ด ๋™์ผํ•˜๊ฒŒ ์›€์ง์ž„
    • ์ง€์—ฐ ์‹œ๊ฐ„: ~100ms

์ข…๋ฃŒ:

  • q ํ‚ค: ํ”„๋กœ๊ทธ๋žจ ์ข…๋ฃŒ
  • Ctrl+C: ๊ฐ•์ œ ์ข…๋ฃŒ

๐Ÿ“ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

DiSRHiT/
โ”œโ”€โ”€ AI_computer/                 # ์ œ์–ด ์ปดํ“จํ„ฐ (Python 99.9%)
โ”‚   โ”œโ”€โ”€ main_delay.py            # ๋ฉ”์ธ ์† ์ถ”์  + Socket ํด๋ผ์ด์–ธํŠธ
โ”‚   โ”œโ”€โ”€ camera.py                # ์›น์บ  ํ…Œ์ŠคํŠธ (์นด๋ฉ”๋ผ 0)
โ”‚   โ”œโ”€โ”€ camera2.py               # ์›น์บ  ํ…Œ์ŠคํŠธ (์นด๋ฉ”๋ผ 1)
โ”‚   โ””โ”€โ”€ requirements.txt         # ์˜์กด์„ฑ
โ”‚
โ”œโ”€โ”€ Hand_Robot/                  # ๋กœ๋ด‡ ํŒ” (Raspberry Pi)
โ”‚   โ”œโ”€โ”€ main.py                  # Socket ์„œ๋ฒ„ + ์„œ๋ณด ์ œ์–ด
โ”‚   โ”œโ”€โ”€ requirements.txt         # ์˜์กด์„ฑ
โ”‚   โ”œโ”€โ”€ bin/                     # ์œ ํ‹ธ๋ฆฌํ‹ฐ ์Šคํฌ๋ฆฝํŠธ
โ”‚   โ”‚   โ”œโ”€โ”€ i2cscan.py           # I2C ์žฅ์น˜ ์Šค์บ”
โ”‚   โ”‚   โ”œโ”€โ”€ ftdi_urls.py         # FTDI ์žฅ์น˜ ํ™•์ธ
โ”‚   โ”‚   โ””โ”€โ”€ pyterm.py            # ์‹œ๋ฆฌ์–ผ ํ„ฐ๋ฏธ๋„
โ”‚   โ””โ”€โ”€ research_data/
โ”‚       โ””โ”€โ”€ socket_client.py     # Socket ํ…Œ์ŠคํŠธ ํด๋ผ์ด์–ธํŠธ
โ”‚
โ”œโ”€โ”€ profile_image. jpeg           # ํ”„๋กœ์ ํŠธ ์ด๋ฏธ์ง€
โ”œโ”€โ”€ README.md                    # ์ด ๋ฌธ์„œ
โ””โ”€โ”€ test. md                      # ํ…Œ์ŠคํŠธ ๋ฌธ์„œ

๐Ÿ’ป ํ•ต์‹ฌ ์ฝ”๋“œ ๋ถ„์„

์†๊ฐ€๋ฝ ๊ฐ๋„ ๊ณ„์‚ฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜

def draw_finger_angles(image, results, joint_list):
    for hand in results.multi_hand_landmarks:
        for joint in joint_list:
            # 3๊ฐœ ์ ์œผ๋กœ ๊ฐ๋„ ๊ณ„์‚ฐ
            a = np.array([hand.landmark[joint[0]].x, 
                          hand.landmark[joint[0]].y])
            b = np.array([hand.landmark[joint[1]].x, 
                          hand.landmark[joint[1]].y])
            c = np.array([hand.landmark[joint[2]].x, 
                          hand.landmark[joint[2]].y])
            
            # ๋ฒกํ„ฐ ๊ฐ๋„ ๊ณ„์‚ฐ
            radians = np.arctan2(c[1]-b[1], c[0]-b[0]) - \
                      np.arctan2(a[1]-b[1], a[0]-b[0])
            angle = np.abs(radians * 180.0 / np.pi)
            
            # 180๋„ ์ดˆ๊ณผ ์‹œ ๋ณด์ •
            if angle > 180. 0:
                angle = 360 - angle
            
            # ์†๊ฐ€๋ฝ๋ณ„ ๊ฐ๋„ ๋ณด์ •
            if cnt < 4:  # ์—„์ง€~์•ฝ์ง€
                angle = 180 - angle
            if cnt >= 4 and cnt <= 7:  # ์ค‘๊ฐ„ ๋งˆ๋””
                if angle > 80:
                    angle = 180 - angle

์›๋ฆฌ:

  1. 3๊ฐœ ๋žœ๋“œ๋งˆํฌ ์ถ”์ถœ (๊ด€์ ˆ ์–‘์ชฝ + ์ค‘์‹ฌ)
  2. 2๊ฐœ ๋ฒกํ„ฐ ์ƒ์„ฑ
  3. arctan2๋กœ ๊ฐ ๋ฒกํ„ฐ ๊ฐ๋„ ๊ณ„์‚ฐ
  4. ๋‘ ๊ฐ๋„ ์ฐจ์ด๋กœ ๊ด€์ ˆ ๊ฐ๋„ ๋„์ถœ
  5. ์†๊ฐ€๋ฝ๋ณ„ ๋ณด์ • ์ ์šฉ

Socket ์„œ๋ฒ„ (๋ฉ€ํ‹ฐ ํด๋ผ์ด์–ธํŠธ)

def handle_client(client_socket, addr):
    print(f"[Socket] Connected by:  {addr[0]}:{addr[1]}")
    
    while True: 
        try:
            data = client_socket.recv(1024)
            if not data:
                break
            
            # ๋‹ค๋ฅธ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ธŒ๋กœ๋“œ์บ์ŠคํŠธ
            for client in client_sockets:
                if client != client_socket:
                    client. send(data)
            
            # ๋ช…๋ น ํŒŒ์‹ฑ
            command = data. decode().split(':')
            if command[0] == 'action':
                # 11๊ฐœ ์„œ๋ณด ๋™์‹œ ์—…๋ฐ์ดํŠธ (๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ)
                threads = []
                for index in range(11):
                    t = threading.Thread(
                        target=append_angle,
                        args=(index, command[index+1])
                    )
                    threads.append(t)
                    t.start()
                
        except ConnectionResetError:
            break
    
    client_sockets.remove(client_socket)

์„œ๋ณด PWM ์ œ์–ด

def SetPos(self, pos):
    # ๊ฐ๋„ (0~180ยฐ) โ†’ PWM ํŽ„์Šค (150~650)
    pulse = (650-150) * pos/180 + 150 + self.m_ZeroOffset
    
    # PCA9685๋กœ PWM ์‹ ํ˜ธ ์ „์†ก
    self. mPwm.set_pwm(self.mChannel, 0, int(pulse))

PWM ํƒ€์ด๋ฐ:

  • ์ฃผํŒŒ์ˆ˜: 60Hz (16. 67ms ์ฃผ๊ธฐ)
  • ํŽ„์Šค ๋ฒ”์œ„: 150~650 (4096 ๋‹จ๊ณ„ ์ค‘)
  • 0ยฐ: 0. 61ms, 90ยฐ: 1.53ms, 180ยฐ: 2.45ms

๐Ÿ”ง ๋ฌธ์ œ ํ•ด๊ฒฐ

1. Socket ์—ฐ๊ฒฐ ์‹คํŒจ

์ฆ์ƒ:

[Socket][Error] Connection refused

ํ•ด๊ฒฐ:

# 1.  IP ์ฃผ์†Œ ํ™•์ธ
hostname -I

# 2. ๋ฐฉํ™”๋ฒฝ ํ™•์ธ
sudo ufw allow 7672

# 3. ์„œ๋ฒ„ ์žฌ์‹œ์ž‘
python3 main.py

2. I2C ์žฅ์น˜ ์ธ์‹ ์•ˆ ๋จ

์ฆ์ƒ:

IOError: [Errno 2] No such file or directory

ํ•ด๊ฒฐ:

# I2C ํ™œ์„ฑํ™” ํ™•์ธ
ls /dev/i2c*
# /dev/i2c-1 ์žˆ์–ด์•ผ ํ•จ

# I2C ์ฃผ์†Œ ์Šค์บ”
sudo i2cdetect -y 1

# I2C ๋„๊ตฌ ์„ค์น˜
sudo apt-get install i2c-tools

3. ์„œ๋ณด ๋–จ๋ฆผ ํ˜„์ƒ

์ฆ์ƒ:

  • ์„œ๋ณด๊ฐ€ ๋ฏธ์„ธํ•˜๊ฒŒ ๋–จ๋ฆผ
  • ๊ฐ๋„๊ฐ€ ๋ถˆ์•ˆ์ •

ํ•ด๊ฒฐ:

# 1. ์ „์› ๊ณต๊ธ‰ ํ™•์ธ (5V 2A ์ด์ƒ)
# 2. ์บํŒจ์‹œํ„ฐ ์ถ”๊ฐ€ (1000ฮผF)
# 3. ๋ฐ๋“œ์กด ์„ค์ •

def SetPos(self, pos):
    # ๊ฐ๋„ ๋ณ€ํ™”๊ฐ€ 2๋„ ๋ฏธ๋งŒ์ด๋ฉด ๋ฌด์‹œ
    if abs(pos - self.last_pos) < 2:
        return
    
    pulse = (650-150) * pos/180 + 150 + self.m_ZeroOffset
    self.mPwm. set_pwm(self.mChannel, 0, int(pulse))
    self.last_pos = pos

4. MediaPipe ๋А๋ฆผ

์ฆ์ƒ:

FPS:  10~15 (๋ชฉํ‘œ: 30)

ํ•ด๊ฒฐ:

# 1. ํ•ด์ƒ๋„ ๋‚ฎ์ถ”๊ธฐ
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

# 2. ๋ชจ๋ธ ๋ณต์žก๋„ ๋‚ฎ์ถ”๊ธฐ
mp_hands. Hands(
    model_complexity=0,  # 0: ๋น ๋ฆ„, 1: ์ •ํ™•
    min_detection_confidence=0.5,
    min_tracking_confidence=0.5
)

# 3. GPU ์‚ฌ์šฉ (๊ฐ€๋Šฅ ์‹œ)
mp_hands. Hands(
    static_image_mode=False,
    max_num_hands=1
)

๐Ÿ“Š ์„ฑ๋Šฅ ์ง€ํ‘œ

์‹œ์Šคํ…œ ์„ฑ๋Šฅ

ํ•ญ๋ชฉ ์ˆ˜์น˜ ๋น„๊ณ 
FPS 25~30 ์›น์บ  30fps ๊ธฐ์ค€
์ง€์—ฐ ์‹œ๊ฐ„ ~100ms AI โ†’ Robot
ํ†ต์‹  ์†๋„ <10ms Local network
์„œ๋ณด ์‘๋‹ต ~60ms PWM 60Hz
์ •ํ™•๋„ ยฑ3ยฐ ์†๊ฐ€๋ฝ ๊ฐ๋„

๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ

AI Computer:

  • CPU: 40~60% (i5 ์ด์ƒ)
  • RAM: ~500MB
  • GPU: MediaPipe (์„ ํƒ)

Raspberry Pi:

  • CPU: 20~30%
  • RAM: ~200MB
  • I2C ๋Œ€์—ญํญ: ~100kbps

๐ŸŽฏ ํ™œ์šฉ ์‚ฌ๋ก€

1. ์žฌ๋‚œ ๊ตฌ์กฐ

์‹œ๋‚˜๋ฆฌ์˜ค:

์ง€์ง„ โ†’ ๊ฑด๋ฌผ ๋ถ•๊ดด โ†’ 2์ฐจ ๋ถ•๊ดด ์œ„ํ—˜
       โ†“
DiSRHiT ํˆฌ์ž… โ†’ ์›๊ฒฉ ์กฐ์ข…
       โ†“
์ƒ์กด์ž ํƒ์ƒ‰ โ†’ ๋ฌผํ’ˆ ์ „๋‹ฌ โ†’ ๊ตฌ์กฐ

2. ์œ„ํ—˜ ๋ฌผ์งˆ ์ฒ˜๋ฆฌ

  • ๋ฐฉ์‚ฌ๋Šฅ ์˜ค์—ผ ์ง€์—ญ
  • ํ™”ํ•™ ๋ฌผ์งˆ ์œ ์ถœ ํ˜„์žฅ
  • ํญ๋ฐœ๋ฌผ ์ œ๊ฑฐ

3. ์˜๋ฃŒ ์žฌํ™œ

  • ์† ๊ธฐ๋Šฅ ํšŒ๋ณต ํ›ˆ๋ จ
  • ์›๊ฒฉ ์žฌํ™œ ์น˜๋ฃŒ
  • ์† ์›€์ง์ž„ ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘

๐Ÿค ๊ธฐ์—ฌํ•˜๊ธฐ

๊ธฐ์—ฌ๋Š” ์–ธ์ œ๋‚˜ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค! ๐ŸŽ‰

๊ธฐ์—ฌ ๋ฐฉ๋ฒ•

  1. Fork ์ด ์ €์žฅ์†Œ
  2. Feature ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ: git checkout -b feature/AmazingFeature
  3. ๋ณ€๊ฒฝ์‚ฌํ•ญ ์ปค๋ฐ‹: git commit -m 'Add some AmazingFeature'
  4. ๋ธŒ๋žœ์น˜์— Push: git push origin feature/AmazingFeature
  5. Pull Request ์ƒ์„ฑ

๊ฐœ์„  ์•„์ด๋””์–ด

  • ์–‘์† ์ง€์›
  • ํž˜ ํ”ผ๋“œ๋ฐฑ ์ถ”๊ฐ€
  • WebRTC ์˜์ƒ ์ŠคํŠธ๋ฆฌ๋ฐ
  • ์ž์œจ ์ฃผํ–‰ ๊ธฐ๋Šฅ
  • ์Œ์„ฑ ๋ช…๋ น ํ†ตํ•ฉ

๐Ÿ“œ ๋ผ์ด์„ ์Šค

์ด ํ”„๋กœ์ ํŠธ๋Š” MIT License ํ•˜์— ๋ฐฐํฌ๋ฉ๋‹ˆ๋‹ค.


๐Ÿ“ž ์—ฐ๋ฝ์ฒ˜

ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ์ž: Deamonio

[Email](mailto:hyun0810d@gmail. com) GitHub

ํ”„๋กœ์ ํŠธ ๋งํฌ: https://github.com/Deamonio/DiSRHiT


๐Ÿ™ ๊ฐ์‚ฌ์˜ ๋ง

MediaPipe Raspberry Pi Adafruit OpenCV
์† ์ถ”์  ํ•˜๋“œ์›จ์–ด PWM ๋“œ๋ผ์ด๋ฒ„ ์˜์ƒ ์ฒ˜๋ฆฌ

ํŠน๋ณ„ ๊ฐ์‚ฌ:

  • ๐Ÿ–๏ธ Google MediaPipe - ์ •ํ™•ํ•œ ์† ์ถ”์ 
  • ๐Ÿ“ Raspberry Pi Foundation - ์ €๋ ดํ•œ ์ปดํ“จํŒ… ํŒŒ์›Œ
  • โšก Adafruit - ํ›Œ๋ฅญํ•œ PCA9685 ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
  • ๐Ÿ‘๏ธ OpenCV Community - ์˜์ƒ ์ฒ˜๋ฆฌ ๋„๊ตฌ

โญ ์ด ํ”„๋กœ์ ํŠธ๊ฐ€ ๋งˆ์Œ์— ๋“œ์…จ๋‹ค๋ฉด Star๋ฅผ ๋ˆŒ๋Ÿฌ์ฃผ์„ธ์š”!

Star History Chart


Made with โค๏ธ and precision

"Saving lives through technology"


ยฉ 2025 Deamonio. All rights reserved.

โฌ† ๋งจ ์œ„๋กœ ๋Œ์•„๊ฐ€๊ธฐ

About

Disaster Site Rescue Hand Tracking Robot(my favorite production)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages