17浏览
查看: 17|回复: 2

[M10项目] 行空板M10扩展板——行空智能跟随垃圾桶

[复制链接]
本帖最后由 云天 于 2025-6-30 10:54 编辑

【项目背景】
在日常生活中,打扫卫生时常常需要频繁移动垃圾桶,这给使用者带来了诸多不便。为了解决这一问题,我计划设计一个行空智能跟随垃圾桶,它能够在听到我的呼唤后自动跟随我,方便我在打扫过程中随时使用。经过研究和尝试,我选择了在行空板M10上安装Snowboy库进行离线语音唤醒,并使用OpenCV进行人体检测,同时借助硅基流动平台的图像理解大模型进行图像分析,以实现这一功能。
【项目设计】
我将设计一个行空智能跟随垃圾桶,其主要功能如下:
离线语音唤醒通过安装在行空板M10上的Snowboy库,垃圾桶能够离线识别我的唤醒词,“你好小云”,并迅速做出响应。
人体检测与图像分析垃圾桶会旋转并使用OpenCV进行人体检测,若未检测到人体,则旋转一定角度(90度)再次检测,直至回到起点。一旦检测到人体,垃圾桶会将照片上传至硅基流动平台进行图像分析,判断是否有人拿着打扫工具。
自动跟随与避障如果发现有人拿着打扫工具,垃圾桶会驱动电机前进,并通过超声波传感器测量与人的距离,当距离达到30cm时自动停止,确保在打扫室内卫生时能够方便地跟随使用者。
【制作步骤】
1.安装依赖库
sudo apt-get install python-pyaudio python3-pyaudio swig
2.下载代码
3.安装puaduio库
sudo pip3 install pyaudio
4.生成个人唤醒词模型
网址https://snowboy.hahack.com/,方法:记录3个唤醒词示例,并将其提交以生成.pmdl文件。
(1)启用麦克风(Chrome需要)
(2)单击录制并等待准备就绪
(3)说出你的醒语,等待结束
(4)重复,直到你有3个例子
(5)输入模型名称,提交音频,然后单击“保存模型”按钮
(6)下载模型

行空板M10扩展板——行空智能跟随垃圾桶图1

5.将模型上传到行空板
行空板M10扩展板——行空智能跟随垃圾桶图2

【代码编写】
1.修改snowboy/examples/demo.py代码,实现直接加载指定唤醒词模型
#if len(sys.argv) == 1:
#    print("Error: need to specify model name")
#    print("Usage: python demo.py your.model")
#    sys.exit(-1)

#model = sys.argv[1]
model = "/root/snowboy/resources/models/xiaoxing.pmdl"      
2.修改snowboy/examples/demo.py/snowboydecoder.py文件,实现人体检测、图像分析、电机驱动。
(1)加载语音提醒,“我在呢”,“看到你了,我来了”                               
DETECT_Hello = os.path.join(TOP_DIR, "resources/xiaoxing.wav")
DETECT_COME = os.path.join(TOP_DIR, "resources/come.wav")
(2)使用OpenCV的Haar 检测器,进行人体检测。如检测到人体将此图像进行Base64编码。
import cv2
# 加载 Haar 检测器
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
def camera():
    global bs,cap
    if bs==0:
        # 打开摄像头
        cap = cv2.VideoCapture(0)  # 参数 0 表示使用默认摄像头
        if not cap.isOpened():
           print("无法打开摄像头")
           return -1
        bs=1
    # 读取一帧
    ret, frame = cap.read()
    if not ret:
        print("无法读取帧")
        return 0
     # 检测行人
    # 转换为灰度图
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    # 检测人脸
    faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
    # 判断是否有人
    if len(faces) > 0:
        play_audio_file(DETECT_DING)
        print("有人")
        # 将 OpenCV 的 BGR 图像转换为 PIL 的 RGB 图像
        frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        pil_image = Image.fromarray(frame_rgb)
        # 转换为 Base64 编码
        base64_image = convert_image_to_webp_base64(pil_image)
        if base64_image:
            print("Base64 编码成功!")
            # 在这里可以处理 Base64 编码的字符串,例如打印或发送到服务器
            print(base64_image[:20])  # 打印前 100 个字符作为示例
            Vlcontent=QwenVL(base64_image)
            print(Vlcontent)
            if "是" in Vlcontent:
                play_audio_file(DETECT_COME)
                print("yes")
                return 1
            else:
                print("no")
                return 0
        else:
            print("Base64 编码失败!")
            return 0
    else:
        play_audio_file(DETECT_DONG)
        print("无人")
        return 0
def convert_image_to_webp_base64(image):
    """
    将图像对象转换为 WebP 格式的 Base64 编码字符串。
    :param image: PIL.Image 对象
    :return: Base64 编码字符串
    """
    try:
        byte_arr = io.BytesIO()
        image.save(byte_arr, format='webp')
        byte_arr = byte_arr.getvalue()
        base64_str = base64.b64encode(byte_arr).decode('utf-8')
        return base64_str
    except IOError:
        print("Error: Unable to convert the image to WebP Base64")
        return None
(3)使用硅基流动的图像理解大模型,进行图像分析,检测是否有人拿着打扫工具。                                   
def QwenVL(base64_url):
    response = client.chat.completions.create(
        model="Qwen/Qwen2-VL-72B-Instruct",
        messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {
                        "url": "data:image/jpg;base64,"+base64_url
                    }
                },
                {
                    "type": "text",
                    "text": "请看一下这张图像中,如果有一个人手中拿着打扫工具,请回复是,否则回复否。"
                }
        }],
        stream=False
)
    return response.choices[0].message.content
(4)唤醒后,控制电机转向并检测,识别到目标,驱动电机前进,并利用超声传感器测距。                 
def play_audio_file(fname=DETECT_Hello):
    """Simple callback function to play a wave file. By default it plays
    a Ding sound.

    :param str fname: wave file name
    :return: None
    """

    ding_wav = wave.open(fname, 'rb')
    ding_data = ding_wav.readframes(ding_wav.getnframes())
    with no_alsa_error():
        audio = pyaudio.PyAudio()
    stream_out = audio.open(
        format=audio.get_format_from_width(ding_wav.getsampwidth()),
        channels=ding_wav.getnchannels(),
        rate=ding_wav.getframerate(), input=False, output=True)
    stream_out.start_stream()
    stream_out.write(ding_data)
    time.sleep(0.2)
    stream_out.stop_stream()
    stream_out.close()
    audio.terminate()
    if fname==DETECT_Hello:
        print("已唤醒")
        for i in range(4):
            j=camera()
            if j==0:
                #转向
                turn(1,800)
                time.sleep(0.3)
                stop()
                time.sleep(4)
                continue
            else:
                break
        if j==1:
           print("前进")
           #前进
           while True:
             print(urm091.distance_cm())
             if urm091.distance_cm()>30:
               goahead(1,800)
             else:
               stop()
               break

(5)电机驱动
def goahead(direction,PWM):
    p_p23_pwm.write_analog(PWM)
    p_p24_out.write_digital(direction)
    p_p9_out.write_digital(direction)
    p_p21_pwm.write_analog(PWM)
    p_p1_out.write_digital(1-direction)
    p_p4_out.write_digital(1-direction)
def turn(direction,PWM):
    p_p23_pwm.write_analog(PWM)
    p_p24_out.write_digital(direction)
    p_p9_out.write_digital(direction)
    p_p21_pwm.write_analog(PWM)
    p_p1_out.write_digital(direction)
    p_p4_out.write_digital(direction)
def stop():
    p_p23_pwm.write_analog(0)
    p_p21_pwm.write_analog(0)

【硬件组装】
1.底盘使用麦克纳姆轮,两个两路电机驱动,两节锂电池供电。     
行空板M10扩展板——行空智能跟随垃圾桶图3     
2.使用行空板M10及扩展上的相应引脚(代码中有设置),连接电机驱动、超声波传感器。因使用了独立的电机驱动,扩展板上的电机驱动引脚未使用。  
行空板M10扩展板——行空智能跟随垃圾桶图7
3.固定垃圾桶
行空板M10扩展板——行空智能跟随垃圾桶图6
4.固定摄像头
行空板M10扩展板——行空智能跟随垃圾桶图4

行空板M10扩展板——行空智能跟随垃圾桶图5

【演示视频】



木子哦  管理员

发表于 4 小时前

感觉可以做个判断,如果人拿着扫把,垃圾桶跟随人走;如果人没有拿着打扫工具(代表打扫完了),垃圾桶自动回到他该回的位置。
回复

使用道具 举报

云天  初级技神
 楼主|

发表于 1 小时前

木子哦 发表于 2025-6-30 12:00
感觉可以做个判断,如果人拿着扫把,垃圾桶跟随人走;如果人没有拿着打扫工具(代表打扫完了),垃圾桶自动 ...

好的好的,这样就更好了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail