邬嘉文:GPT机器人制作指引
邬嘉文:GPT机器人制作指引
邬嘉文:GPT机器人制作指引 邬嘉文:GPT机器人制作指引 Created on April 16, 2024 chat.py • Macbook新建终端窗口,通过cd指令到达项目目录,输入python3 chat.py • 国内大模型(kimi,GLM)目前json格式返回不是很稳定。这里使用OPENAI API。 import json import socket from openai import OpenAI import pygame import struct OPEN API KEY='填写API KEY' 默认科学上网 client = OpenAI(api key=OPEN API KEY) def send to iphone(kaomoji, audio file): HOST = '192.168.1.115' PORT = 12345 这里改iPhone IP地址。 try: with socket.socket(socket.AF INET, socket.SOCK STREAM) as s: s.connect((HOST, PORT)) kaomoji data = kaomoji.encode() kaomoji len = len(kaomoji data) with open(audio file, 'rb') as f: audio data = f.read() audio len = len(audio data) data = struct.pack(f'!I{kaomoji len}sI{audio len}s', kaomoji len, kaomoji data, audio len, audio data) s.sendall(data) except: print("iPhone连接失败,请检查IP地址和端口号。") def play audio(file path): pygame.mixer.init() pygame.mixer.music.load(file path) pygame.mixer.music.play() while pygame.mixer.music.get busy(): pygame.time.delay(100) pygame.mixer.quit() while True: prompt = input("请输入对话内容,输入quit退出: ") if prompt.lower() == 'quit': break response = client.chat.completions.create( model="gpt 3.5 turbo 0125", response format={"type": "json object"}, messages=[ {"role": "system", "content": "假设你是一个可以和人类对话的具身机器人,反应内容包括响应内容,以及对应的kaomoji表情和头部动作(双轴舵机转动参数)。以json格式返回,响应内容定义为response,表情定义为kaomoji,kaomoji表情要反映响应内容情感。与表情对应的头部动作水平角度(无需单位)为servoX,范围是10 170,面向正前方是90。与表情对应的头部动作垂直角度(无需单位)为servoY,范围是10 170,水平面是90。"}, {"role": "user", "content": prompt}, ] ) result = json.loads(response.choices[0].message.content) print(response.choices[0].message.content) 将response内容转为实时语音 speech response = client.audio.speech.create( model="tts 1", voice="alloy", input=result['response'], ) speech response.stream to file("output.mp3") send to iphone(result['kaomoji'], "output.mp3") with socket.socket(socket.AF INET, socket.SOCK STREAM) as s: s.connect(('127.0.0.1', 7892)) data = json.dumps({"servoX": result['servoX'], "servoY": result['servoY']}).encode() s.sendall(data) Troubleshooting • 在整个搭建过程中,因环境差异遇到大量错误信息,请多问GPT和GOOGLE。 • 更多参考:手把手教会你做"机器人男友"搭建指引 • 查询后,问题仍未解决,可在群里请教大神。 • 我是小白用户,不一定能解答你遇到的问题 || • 不要放弃。 • 群满了,可以加微信:AAAAAAAJ (一定要备注暗号“111” 拉你进群) 手把手教会你做"机器人男友"搭建指引 chat.py • Macbook新建终端窗口,通过cd指令到达项目目录,输入python3 chat.py • 国内大模型(kimi,GLM)目前json格式返回不是很稳定。这里使用OPENAI API。 import json import socket from openai import OpenAI import pygame import struct OPEN API KEY='填写API KEY' 默认科学上网 client = OpenAI(api key=OPEN API KEY) def send to iphone(kaomoji, audio file): HOST = '192.168.1.115' PORT = 12345 这里改iPhone IP地址。 try: with socket.socket(socket.AF INET, socket.SOCK STREAM) as s: s.connect((HOST, PORT)) kaomoji data = kaomoji.encode() kaomoji len = len(kaomoji data) with open(audio file, 'rb') as f: audio data = f.read() audio len = len(audio data) data = struct.pack(f'!I{kaomoji len}sI{audio len}s', kaomoji len, kaomoji data, audio len, audio data) s.sendall(data) except: print("iPhone连接失败,请检查IP地址和端口号。") def play audio(file path): pygame.mixer.init() pygame.mixer.music.load(file path) pygame.mixer.music.play() while pygame.mixer.music.get busy(): pygame.time.delay(100) pygame.mixer.quit() while True: prompt = input("请输入对话内容,输入quit退出: ") if prompt.lower() == 'quit': break response = client.chat.completions.create( model="gpt 3.5 turbo 0125", response format={"type": "json object"}, messages=[ {"role": "system", "content": "假设你是一个可以和人类对话的具身机器人,反应内容包括响应内容,以及对应的kaomoji表情和头部动作(双轴舵机转动参数)。以json格式返回,响应内容定义为response,表情定义为kaomoji,kaomoji表情要反映响应内容情感。与表情对应的头部动作水平角度(无需单位)为servoX,范围是10 170,面向正前方是90。与表情对应的头部动作垂直角度(无需单位)为servoY,范围是10 170,水平面是90。"}, {"role": "user", "content": prompt}, ] ) result = json.loads(response.choices[0].message.content) print(response.choices[0].message.content) 将response内容转为实时语音 speech response = client.audio.speech.create( model="tts 1", voice="alloy", input=result['response'], ) speech response.stream to file("output.mp3") send to iphone(result['kaomoji'], "output.mp3") with socket.socket(socket.AF INET, socket.SOCK STREAM) as s: s.connect(('127.0.0.1', 7892)) data = json.dumps({"servoX": result['servoX'], "servoY": result['servoY']}).encode() s.sendall(data) import json import socket from openai import OpenAI import pygame import struct OPEN API KEY='填写API KEY' 默认科学上网 client = OpenAI(api key=OPEN API KEY) def send to iphone(kaomoji, audio file): HOST = '192.168.1.115' PORT = 12345 这里改iPhone IP地址。 try: with socket.socket(socket.AF INET, socket.SOCK STREAM) as s: s.connect((HOST, PORT)) kaomoji data = kaomoji.encode() kaomoji len = len(kaomoji data) with open(audio file, 'rb') as f: audio data = f.read() audio len = len(audio data) data = struct.pack(f'!I{kaomoji len}sI{audio len}s', kaomoji len, kaomoji data, audio len, audio data) s.sendall(data) except: print("iPhone连接失败,请检查IP地址和端口号。") def play audio(file path): pygame.mixer.init() pygame.mixer.music.load(file path) pygame.mixer.music.play() while pygame.mixer.music.get busy(): pygame.time.delay(100) pygame.mixer.quit() while True: prompt = input("请输入对话内容,输入quit退出: ") if prompt.lower() == 'quit': break response = client.chat.completions.create( model="gpt 3.5 turbo 0125", response format={"type": "json object"}, messages=[ {"role": "system", "content": "假设你是一个可以和人类对话的具身机器人,反应内容包括响应内容,以及对应的kaomoji表情和头部动作(双轴舵机转动参数)。以json格式返回,响应内容定义为response,表情定义为kaomoji,kaomoji表情要反映响应内容情感。与表情对应的头部动作水平角度(无需单位)为servoX,范围是10 170,面向正前方是90。与表情对应的头部动作垂直角度(无需单位)为servoY,范围是10 170,水平面是90。"}, {"role": "user", "content": prompt}, ] ) result = json.loads(response.choices[0].message.content) print(response.choices[0].message.content) 将response内容转为实时语音 speech response = client.audio.speech.create( model="tts 1", voice="alloy", input=result['response'], ) speech response.stream to file("output.mp3") send to iphone(result['kaomoji'], "output.mp3") with socket.socket(socket.AF INET, socket.SOCK STREAM) as s: s.connect(('127.0.0.1', 7892)) data = json.dumps({"servoX": result['servoX'], "servoY": result['servoY']}).encode() s.sendall(data) import json import socket from openai import OpenAI import pygame import struct OPEN API KEY='填写API KEY' 默认科学上网 client = OpenAI(api key=OPEN API KEY) def send to iphone(kaomoji, audio file): HOST = '192.168.1.115' PORT = 12345 这里改iPhone IP地址。 try: with socket.socket(socket.AF INET, socket.SOCK STREAM) as s: s.connect((HOST, PORT)) kaomoji data = kaomoji.encode() kaomoji len = len(kaomoji data) with open(audio file, 'rb') as f: audio data = f.read() audio len = len(audio data) data = struct.pack(f'!I{kaomoji len}sI{audio len}s', kaomoji len, kaomoji data, audio len, audio data) s.sendall(data) except: print("iPhone连接失败,请检查IP地址和端口号。") def play audio(file path): pygame.mixer.init() pygame.mixer.music.load(file path) pygame.mixer.music.play() while pygame.mixer.music.get busy(): pygame.time.delay(100) pygame.mixer.quit() while True: prompt = input("请输入对话内容,输入quit退出: ") if prompt.lower() == 'quit': break response = client.chat.completions.create( model="gpt 3.5 turbo 0125", response format={"type": "json object"}, messages=[ {"role": "system", "content": "假设你是一个可以和人类对话的具身机器人,反应内容包括响应内容,以及对应的kaomoji表情和头部动作(双轴舵机转动参数)。以json格式返回,响应内容定义为response,表情定义为kaomoji,kaomoji表情要反映响应内容情感。与表情对应的头部动作水平角度(无需单位)为servoX,范围是10 170,面向正前方是90。与表情对应的头部动作垂直角度(无需单位)为servoY,范围是10 170,水平面是90。"}, {"role": "user", "content": prompt}, ] ) result = json.loads(response.choices[0].message.content) print(response.choices[0].message.content) 将response内容转为实时语音 speech response = client.audio.speech.create( model="tts 1", voice="alloy", input=result['response'], ) speech response.stream to file("output.mp3") send to iphone(result['kaomoji'], "output.mp3") with socket.socket(socket.AF INET, socket.SOCK STREAM) as s: s.connect(('127.0.0.1', 7892)) data = json.dumps({"servoX": result['servoX'], "servoY": result['servoY']}).encode() s.sendall(data) Troubleshooting • 在整个搭建过程中,因环境差异遇到大量错误信息,请多问GPT和GOOGLE。 • 更多参考:手把手教会你做"机器人男友"搭建指引 手把手教会你做"机器人男友"搭建指引 • 查询后,问题仍未解决,可在群里请教大神。 • 我是小白用户,不一定能解答你遇到的问题 || • 不要放弃。 • 群满了,可以加微信:AAAAAAAJ (一定要备注暗号“111” 拉你进群) 制作过程及代码 💡 作者:邬嘉文 上一篇效果:邬嘉文:GPT具身对话机器人 邬嘉文:GPT具身对话机器人 作者:邬嘉文 上一篇效果:邬嘉文:GPT具身对话机器人 邬嘉文:GPT具身对话机器人 基础要求 • 通过Bilibili学习Python、Arduino IDE安装部署。 • 通过Google查找报错信息及解决方案。 • 充值大语言模型API,获取API KEY。 • 有一个科学的环境。 硬件方案 参考案例 Headshot Tracking || OpenCV | Arduino https://www.youtube.com/watch?v=f2TUxoaKIsA www.youtube.com Github仓库 https://github.com/rizkydermawan1992/face detection GitHub rizkydermawan1992/Face Detection Contribute to rizkydermawan1992/Face Detection development by creating an account on GitHub. 核心代码:Python通过pyfirmata和arduino通讯 https://github.com/rizkydermawan1992/Face Detection/blob/main/facetracking.py 硬件购置 舵机 • 淘宝关键字:9g 舵机 云台 • 扭矩:1.6kg·cm(4.8V) • 优点:便宜 • 缺点:有点不够力 MCU控制主板 • Arduino R4 WIFI https://item.taobao.com/item.htm?id=747173482966&spm=a1z10.3 c.w4002 17654493359.54.1547788aM0gXE6&skuId=5258642628188 item.taobao.com • 板子比较 Arduino UNO R4 Arduino UNO R3 国产 Arduino ESP32 优点 支持TypeC连接,安卓手机可直接供电 兼容性更好,升级Firmata容易 适合硬件玩家,便宜 适合硬件玩家,便宜 缺点 Firmata升级有兼容性问题,需要改源码 USB接口比较老款,需要转接线 价格 200 150 100 30 Arduino UNO R4 Arduino UNO R4 Arduino UNO R3 Arduino UNO R3 国产 Arduino 国产 Arduino ESP32 ESP32 优点 优点 支持TypeC连接,安卓手机可直接供电 支持TypeC连接,安卓手机可直接供电 兼容性更好,升级Firmata容易 兼容性更好,升级Firmata容易 适合硬件玩家,便宜 适合硬件玩家,便宜 适合硬件玩家,便宜 适合硬件玩家,便宜 缺点 缺点 Firmata升级有兼容性问题,需要改源码 Firmata升级有兼容性问题,需要改源码 USB接口比较老款,需要转接线 USB接口比较老款,需要转接线 价格 价格 200 200 150 150 100 100 30 30 Tips:有经验玩家自行选购舵机和MCU。 杜邦线 • 公对公 6条 https://item.taobao.com/item.htm? u=223phqqd23e&id=538759249552&spm=a1z09.2.0.0.56b12e8dxVtoiF item.taobao.com 硬件组装 舵机接线 • 3条杜邦线接在一起,如左图。(末端贴纸是arduino赠送的) • 按右图方式接线,让arduino提供5V电源和PWM控制。 云台组装 • 云台有两片竖起胶片,剪掉,换上强力双面胶,把手机粘住。 • 快递盒子做底座,板子可以推到盒子内。 • 字典在旁边压着,防止盒子翻车。 || 环境搭建 Arduino 1. 安装Arduino IDE 2. File Examples Firmata StandardFirmata,写入板子,报错,Google解决方案。 3. R4太新,Board.h文件未覆盖,根据Google指引添加R4到board.h就好,重新写入StandardFirmata。 Python 1. 安装python,3.10兼容性较好。 2. Pip install pygame, openai, socket, pyfirmata ◦ 根据python运行报错信息,补充安装缺少的库。 ◦ Pyfirmata负责Python和Arduino通讯 ◦ 根据python运行报错信息,补充安装缺少的库。 ◦ Pyfirmata负责Python和Arduino通讯 Pythonista 1. iPhone上运行Python IDE,售价68 rmb。 程序运行 Github • 代码是基于macbook+iPhone开发。 • 项目工程由Claude 3 Opus输出。 • 假如修改环境机需求,可以将原代码和需求特性放入到prompt,让Claude重写代码。 • 3个程序需同时运行。 GitHub garmanwu/GPT Embodiment Robot: GPT driven Chat Robot GitHub garmanwu/GPT Embodiment Robot: GPT driven Chat Robot You don't have permission to access this synced block. Please log in and try again. Log In You don't have permission to access this synced block. Please log in and try again. Log In Head.py • 打开macbook的终端窗口,通过cd指令到达项目目录。 • 输入python3 head.py import cv2 from cvzone.FaceDetectionModule import FaceDetector import pyfirmata import numpy as np import socket import json import threading import time cap = cv2.VideoCapture(0) ws, hs = 1280, 720 cap.set(3, ws) cap.set(4, hs) if not cap.isOpened(): print("Camera couldn't Access!!!") exit() port = "/dev/cu.usbmodemF412FA64031C2" 改为自己设备的串口号 board = pyfirmata.Arduino(port) servo pinX = board.get pin('d:9:s') pin 9 Arduino servo pinY = board.get pin('d:10:s') pin 10 Arduino detector = FaceDetector() servoPos = [90, 90] initial servo position 默认舵机位置 last data time = 0 import cv2 from cvzone.FaceDetectionModule import FaceDetector import pyfirmata import numpy as np import socket import json import threading import time cap = cv2.VideoCapture(0) ws, hs = 1280, 720 cap.set(3, ws) cap.set(4, hs) if not cap.isOpened(): print("Camera couldn't Access!!!") exit() port = "/dev/cu.usbmodemF412FA64031C2" 改为自己设备的串口号 board = pyfirmata.Arduino(port) servo pinX = board.get pin('d:9:s') pin 9 Arduino servo pinY = board.get pin('d:10:s') pin 10 Arduino detector = FaceDetector() servoPos = [90, 90] initial servo position 默认舵机位置 last data time = 0 import cv2 from cvzone.FaceDetectionModule import FaceDetector import pyfirmata import numpy as np import socket import json import threading import time cap = cv2.VideoCapture(0) ws, hs = 1280, 720 cap.set(3, ws) cap.set(4, hs) if not cap.isOpened(): print("Camera couldn't Access!!!") exit() port = "/dev/cu.usbmodemF412FA64031C2" 改为自己设备的串口号 board