【项目实训】项目工作日志(九)

项目工作日志(九):智能车远程遥控程序

引言

在前一部分的工作中,我们完成了智能车下位机摄像头检测的实现。接下来,我们将集中在智能车运行过程中的远程遥控程序上,通过手柄传输数据到上位机,上位机向下位机传输对应的信息,控制电机启动,使得脉轮旋转,从而完成对智能车的移动控制。本部分记录了远程遥控程序的详细步骤和代码示例。

远程遥控程序

远程遥控程序是智能车控制的重要组成部分,通过手柄和上位机的协作,实现对智能车的精准控制。以下是远程遥控程序的代码实现。

  1. 导入必要的库
    首先,我们需要导入相关库:
import cv2
import threading
import time
import json
import subprocess
import os, sys
# 添加上两层目录
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))) 

from vehicle import MecanumBase, BluetoothPad, ScreenShow
from camera import Camera
from log_info import logger

2.定义远程控制类
编写 RemoteControlCar 类,初始化摄像头、手柄和车体,并启动后台线程处理图像和车体状态:

class RemoteControlCar:
    def __init__(self, cap: Camera = None) -> None:
        path_dir = os.path.abspath(os.path.dirname(__file__))
        self.dir = os.path.join(path_dir, "image_set1")
        if not os.path.exists(self.dir):
            os.mkdir(self.dir)

        self.index = 0
        if cap is None:
            self.cap = Camera(1, 320, 240)
        else:
            self.cap = cap

        self.car = MecanumBase()
        self.car.beep()
        self.display = ScreenShow()
        self.blue_pad = BluetoothPad()

        self.state_base = [0.15, 0.15, 0.3]
        self.state_start = [0.3, 0.3, 0.5]
        self.car_state = [0.0, 0.0, 0.0]
        self.run_flag = False
        self.exit_flag = False
        self.json_data = []

        logger.info("remote control start!!")
        self.img_thread = threading.Thread(target=self.image_process, args=())
        self.img_thread.daemon = True
        self.img_thread.start()

        self.car_process()
        
    def car_process(self):
        pad_exit_flag = False
        while not self.exit_flag:
            keys_val = self.blue_pad.get_stick()
            if keys_val == [-1, -1, -1, -1, 0]:
                pad_exit_flag = False
                self.car_state = [0.0, 0.0, 0.0]
                logger.error("no bluepad")
                self.display.show("no bluepad\n")
                self.car.beep()
                time.sleep(1)
                continue
            else:
                if not pad_exit_flag:
                    self.display.show("press btn control\n 3 pressing record\n 4+2 stop\n 4+v del 30pic\n 4+o del all\n")
                pad_exit_flag = True

            if (keys_val[4] & 1024) != 0:
                self.run_flag = True
            else:
                self.run_flag = False
            if keys_val[4] == 34816:
                self.close()
            elif keys_val[4] == 2052:
                self.del_last3s()
            elif keys_val[4] == 2304:
                self.restart()
            if self.run_flag:
                self.car_state[0] = self.state_base[0]
                self.car_state[1] = -1 * self.state_base[1] * keys_val[0]
                self.car_state[2] = -3.14 * self.state_base[2] * keys_val[2]
            else:
                self.car_state[0] = self.state_start[0] * keys_val[1]
                self.car_state[1] = -1 * self.state_start[1] * keys_val[0]
                self.car_state[2] = -3.14 * self.state_start[2] * keys_val[2]

            self.car.mecanum_wheel(*self.car_state)
            time.sleep(0.05)

    def image_process(self):
        name_length = 4
        
        if os.path.exists(self.dir) is not True:
            os.mkdir(self.dir)
        json_name = "data.json"
        self.json_path = os.path.join(self.dir, json_name)
        
        while not self.exit_flag:
            if self.run_flag:
                data_dict = dict()
                image = self.cap.read()
                img_name = (name_length - len(str(self.index)))*'0' + str(self.index) +'.jpg'
                data_dict["img_path"] = img_name
                image_path = os.path.join(self.dir, img_name)
                cv2.imwrite(image_path, image)
                data_dict["state"] = self.car_state.copy()
                self.json_data.append(data_dict)
                logger.info("image:{}".format(img_name))
                self.index += 1
                if self.index % 10 == 0:
                    self.save_json(self.json_data, self.json_path)
                if self.index % 20 == 0:
                    self.display.show("image:{}\n".format(self.index))
                time.sleep(0.05)
            
    def del_last3s(self):
        self.car.beep()
        for i in range(30):
            try:
                data = self.json_data.pop()
                path = os.path.join(self.dir, data['img_path'])
                os.remove(path)
                self.index -= 1
            except IndexError:
                logger.info("image data zero now")
                return
        self.display.show("image:{}\n".format(self.index))

    def restart(self):
        self.car.beep()
        time.sleep(0.4)
        self.car.beep()
        subprocess.run(["find", self.dir, "-name", "*.jpg", "-delete"])
        self.json_data = []
        self.index = 0
        self.display.show("image:{}\n".format(self.index))

    @staticmethod
    def save_json(json_data, path):
        with open(path, 'w') as fp:
            json.dump(json_data, fp)

    def close(self):
        self.save_json(self.json_data, self.json_path)
        self.display.show("control end!\nimage:{}\n".format(self.index))
        self.exit_flag = True
        self.img_thread.join()
        self.cap.close()

        for i in range(3):
            self.car.beep()
            time.sleep(0.4)

if __name__ == "__main__":
    remote_car = RemoteControlCar()

总结
通过以上步骤,我们完成了智能车远程遥控程序的实现。该程序通过手柄传输数据到上位机,上位机向下位机传输对应的信息,控制电机启动,使得脉轮旋转,从而完成对智能车的移动控制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

弈yi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值