# pythoncar **Repository Path**: wu-junfenggitee/pythoncar ## Basic Information - **Project Name**: pythoncar - **Description**: An intellligent car based on Raspberry Pi: obstacle avoidance, video transimission, object detection, tennis tracking; 基于树莓派的智能小车:自动避障,实时图像传输,目标检测,网球追踪; - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2025-06-06 - **Last Updated**: 2025-06-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # RaspberryCar An intelligent car based on Raspberry-Pi-3. (中文介绍请往后翻) ## Platform Raspberry-Pi-3 L298N Camera (CSI) Ultrasonic ranging sensor Infrared obstacle avoidance sensor Car (4 motors) ## Environment ### On Raspiberry Pi: python 3 RPi.GPIO opencv picamera tensorflow TensorFlow Object Detection API ### On PC: python 3 opencv ## Run ### Obstacle avoidance Based on ultrasonic sensor and infrared sensors. Enter the following commands in Pi Terminal: ``` cd PythonCode python3 main_obstacle_avoidance.py ``` Has been tested. ### Video recording & Video transmittion from Pi to PC Enter the following commands in Pi Terminal: ``` cd PythonCode python3 camera.py ``` Besides, if you want to watch the video from PC, then enter the following commands in PC Terminal: ``` cd PythonCode python3 pc_receiver.py ``` Has been tested. ### Lane tracking The car will drive along the lanes based on camera. Enter the following commands in Pi Terminal: ``` cd PythonCode python3 main_lane_tracking.py ``` Besides, if you want to watch the video with the detected lanes from PC, then enter the following commands in PC Terminal: ``` cd PythonCode python3 pc_receiver.py ``` ### Tennis Tracking The car will first detect the tennis based on its camera, then it will move to track the tennis. Enter the following commands in Pi Terminal: ``` cd PythonCode python3 main_tennis_tracking.py ``` Besides, if you want to watch the video with the detected result from PC, then enter the following commands in PC Terminal: ``` cd PythonCode python3 pc_receiver.py ``` ### Object Detection Based on TensorFLow Object Detection API, using the 'ssdlite_mobilenet_v2_coco_2018_05_09' pre-trained model. Enter the following commands in Pi Terminal: ``` cd PythonCode python3 main_object_detection.py ``` (NOTICE: TensorFlow Object Detection API and the ssdlite model are not contained in the repo. See here to install them [EdjeElectronics/Tutorial to set up TensorFlow Object Detection API on the Raspberry Pi](https://github.com/EdjeElectronics/TensorFlow-Object-Detection-on-the-Raspberry-Pi#tutorial-to-set-up-tensorflow-object-detection-api-on-the-raspberry-pi)) *** ## 简介 本项目是学校项目设计课程内的项目,要求是使用一个基于树莓派的小车来实现一些简单的功能。 本项目适合初次接触树莓派,希望利用树莓派及小车配件实现一些简单功能的同学们。 目前我们实现的功能有: * 自动避障:基于超声波和红外,使小车在运行过程中不会撞上障碍物; * 实时图像传输:将树莓派摄像头拍摄到的视频流传到PC端,并在PC端查看; * 视觉车道循迹:基于视觉,使小车沿车道线行驶; * 目标检测:识别并定位摄像头图像中的各类常见物体; * 网球追踪:基于视觉,使小车追踪一个移动的网球,并与网球保持一定距离。 学校提供的小车的商家是[慧净电子](http://www.hlmcu.com/),商家提供了一些使用教程,适合初学,基于C语言,实现了一些简单的红外避障、红外寻迹、超声波避障和摄像头调用。 本项目选用Python作为编程语言,有几点原因:Python相比较C语言更简明;我们对Python的掌握情况更好一些(C语言没学好啊);方便之后使用tensorflow做一些深度学习的功能。但同时带来的缺点就是运行速度会差一点。 下面我们会对小车配置、功能实现和使用方法进行详细的介绍。本文结构如下: * 配置要求 * 项目架构 * 准备工作 * 硬件调试 * 功能实现(原理介绍) * 功能实现(使用教程) 若想成功实现本项目的功能,请: * 首先确保完成**准备工作** * 之后进行**硬件调试** * 之后在阅读过**功能实现-原理介绍**的基础上 * 根据**功能实现-使用教程**来运行相应程序、实现功能 ## 配置要求 * 树莓派3 * 驱动板(L298N) * CSI摄像头 * 超声波测距传感器 * 红外避障传感器 * 小车车体 + 4个电机 * 电脑 (Ubuntu18.04) ## 项目架构 我们的源代码全部放在PythonCode文件夹内。 我们对每个传感器定义了一个类,放在相应的py文件里,由此可以很清晰方便地对每个传感器进行单独的调试。 名称以main开头的文件是实现相应功能的主程序,在主程序里定义了一个Car类,该类继承了所有传感器的类。 ## 准备工作 ### 重装树莓派的系统 商家给树莓派预装了系统,应该是商家自己改过的,也是几年前的了。强烈建议自己将树莓派的系统进行重装(重装后opencv和tensorflow的安装都会简单很多),推荐安装树莓派的官方系统[Raspbian](https://www.raspberrypi.org/downloads/raspbian/)。安装方法百度一下,教程很多,也很简单。 关于树莓派教程,推荐[树莓派实验室|开箱上手必读](http://shumeipai.nxez.com/hot-explorer#beginner),里面的教程基本准确好用。 ### 使用SSH登录,操作树莓派 对树莓派进行操作的方法有很多: * [连接鼠标键盘](http://shumeipai.nxez.com/2013/09/07/how-to-install-and-activate-raspberry-pi.html) * [使用远程桌面](http://shumeipai.nxez.com/2018/08/31/raspberry-pi-vnc-viewer-configuration-tutorial.html) * [使用PuTTY登录到树莓派](http://shumeipai.nxez.com/2013/09/07/using-putty-to-log-in-to-the-raspberry-pie.html) 我们基本上是使用SSH登录到树莓派进行操作的,也就是使用putty登录。这需要树莓派和PC在同一个局域网下,我们选择让树莓派创建一个WiFi热点,然后让PC连接这个WiFi热点。方法:[创建WiFi热点并开机自启动](https://github.com/Mingrui-Yu/Tutorials/blob/master/Rapberry_Pi/%E5%88%9B%E5%BB%BAwifi%E7%83%AD%E7%82%B9%26%E5%BC%80%E5%90%AFSSH%26putty%E8%BF%9E%E6%8E%A5.md#pi3-%E5%88%9B%E5%BB%BAwifi%E7%83%AD%E7%82%B9--%E5%BC%80%E5%90%AFssh--putty%E8%BF%9E%E6%8E%A5),其中使用了github上一个开源的库create_ap。同时,还要设置热点开机自动启动。另外注意要设置[开启树莓派的SSH服务](https://github.com/Mingrui-Yu/Tutorials/blob/master/Rapberry_Pi/%E5%88%9B%E5%BB%BAwifi%E7%83%AD%E7%82%B9%26%E5%BC%80%E5%90%AFSSH%26putty%E8%BF%9E%E6%8E%A5.md#%E5%BC%80%E5%90%AFssh%E6%9C%8D%E5%8A%A1),否则putty连接会显示失败。 ### 更换下载源 使用官方的源因为众所周知的原因会非常慢且不稳定,所以要换成国内的源。 * [更换apt源](https://github.com/Mingrui-Yu/Tutorials/blob/master/Rapberry_Pi/%E6%9B%B4%E6%8D%A2%E4%B8%8B%E8%BD%BD%E6%BA%90.md#%E5%88%87%E6%8D%A2%E5%88%B0%E5%9B%BD%E5%86%85%E7%9A%84apt-get%E4%B8%8B%E8%BD%BD%E6%BA%90) * [更换pip源](https://github.com/Mingrui-Yu/Tutorials/blob/master/Rapberry_Pi/%E6%9B%B4%E6%8D%A2%E4%B8%8B%E8%BD%BD%E6%BA%90.md#%E5%88%87%E6%8D%A2%E5%88%B0%E5%9B%BD%E5%86%85%E7%9A%84pippip3%E4%B8%8B%E8%BD%BD%E6%BA%90) ### OpenCV安装 使用最新版树莓派系统,可以直接用pip3安装OpenCV。 教程:[python3 + opencv](https://github.com/Mingrui-Yu/Tutorials/blob/master/Rapberry_Pi/%E7%9B%B8%E6%9C%BA%26opencv_python.md#python3--opencv) ## 硬件调试 首先需要确定树莓派、驱动板、传感器之间的连线是正确的。 ### 电机 [直流电机相关知识](https://github.com/Mingrui-Yu/Tutorials/blob/master/Rapberry_Pi/%E7%9B%B4%E6%B5%81%E7%94%B5%E6%9C%BA%E7%9B%B8%E5%85%B3.md#%E7%9B%B4%E6%B5%81%E7%94%B5%E6%9C%BA%E7%9B%B8%E5%85%B3%E7%9F%A5%E8%AF%86) * 工作原理 * H桥 * PWM 电机相关代码在move.py内。需要注意GPIO端口号的设置,python用的是BCM编码。 ![树莓派GPIO编号](https://i.loli.net/2019/10/31/bya1AnwmYDMBKLH.png) 在move.py中,定义了前进、后退、左转、右转、停车功能。转弯是通过左右轮差速实现的。 ### 超声波测距传感器 [超声波测距传感器有关知识](https://github.com/Mingrui-Yu/Tutorials/blob/master/Rapberry_Pi/%E8%B6%85%E5%A3%B0%E6%B3%A2%E4%BC%A0%E6%84%9F%E5%99%A8.md#%E8%B6%85%E5%A3%B0%E6%B3%A2%E4%BC%A0%E6%84%9F%E5%99%A8%E7%9B%B8%E5%85%B3) * 超声波测距基本原理 * 超声波测距程序实现 * 提升测距准确性的方法 超声波相关代码在ultrasound.py内,实现了超声波测距和对测距进行移动平均来减小误差。 ### 红外避障传感器 红外避障相关代码在infrared.py内,InfraredMeasure函数是小车左右的两个红外避障传感器,TrackingMeasure是小车底部两个红外寻线传感器。 注意,红外避障传感器传回0表示前方有障碍物,传回1表示前方无障碍物。 ### 摄像头 调用摄像头需要先在``` sudo raspi-config ```中启用Camera,然后重启。 python调用摄像头有两种方式: * 使用picamera * 使用opencv 我们使用的是picamera方式,因为我们发现使用OpenCV的方式会有延时,它返回的第一帧图像是在镜头初始化那一刻的图像,而不是主程序请求时的图像。 具体调用方法参考 [树莓派(Raspberry Pi)中PiCamera+OpenCV的使用](https://blog.csdn.net/u012005313/article/details/70244747#C0)。 摄像头相关代码在camera.py中,其中实现了: * 摄像头初始化 * 实时图像传输(发送端),注意HOST为PC在此WiFi网络下的IP地址(通过ifconfig查看),PORT设置一个和接收端相同的端口号就可以。 另外注意,程序终止是一定要关闭摄像机(camera.close()),否则下次无法正常打开。 ## 功能实现(原理介绍) ### 自动避障 ![自动避障效果展示](doc/obstacle_avoidance.gif) 基于超声波和红外,使小车在运行过程中不会撞上障碍物。 主程序为main_obstacle_avoidance.py,其思想很简单,超声波传感器测出小车距离前方障碍物的距离,两边的红外传感器测出两边是否有障碍物,根据测量结果进行运动决策和电机控制。 ### 实时图像传输 将树莓派摄像头拍摄到的视频流传到PC端,并在PC端查看。目的是为了便于摄像头姿态的调整和图像处理算法的调试。另外,如果需要的话可以使用传输到PC的图像在PC端进行处理(我们没有实现此功能)。 可选择的传输协议有两种: * TCP:面向连接,提供可靠地服务,无差错,不丢失,不重复;实时性差,效率低;系统资源要求较多。 * UDP:可以无连接;尽最大努力交付,即不保证可靠交付;实时性强,效率高;系统资源要求较少。 我们使用UDP传输协议进行图像传输。具体实现主要分为发送端和接收端两部分 : * 发送端:(camera.py VideoTransimssion) * 图像编码(cv2.imencode) * 校验数据发送(数据长度作为校验) * 编码数据发送(socket.sendall) * 接收端:(pc_receiver.py) * 接收校验数据(4字节数据) * 接收图像编码(校验数据后的第一个数据包) * 简单校验(校验数据 == 编码数据长度) * 图像解码(cv2.imdecode) 其中,发送端在树莓派端运行,接收端在PC端运行。二者同时运行。 ### 视觉车道循迹 基于视觉,使小车沿车道线行驶。环境要求为白色的地板,黑色(深色)的车道线。 ![视觉车道循迹效果展示](doc/lane_tracking.gif) ![视觉车道循迹效果展示2](doc/lane_tracking2.gif) 主程序为main_lane_tracking.py,其流程大致如下: * 车道线检测 * 图像二值化,提取车道线 * 提取车道线的内侧点:在图像的特定行,从中间向两侧检索,检测到0像素点及为车道线点。图像左半边检测到的点即为左车道线点,右半边检测到的点即为右车道线点。(为防止因各种原因车道线部分缺失,我们选择图像4个行提取4组车道线内侧点) * 运动控制 * 运动决策 * 如果两侧车道线都能检测到,则直行 * 如果只能检测到一侧车道线,则有三种情况: * 该侧车道线靠近图像边缘,则还可以继续直行 * 该侧车道线靠近图像中央,则急需转弯,原地旋转 * 该侧车道线位置适中,则缓慢转弯,在前进中转弯 * 如果两侧车道线都检测不到,则维持之前的动作 * 电机控制:根据决策结果,控制小车电机输出 在本实验中,车道线检测部分较容易实现,我们发现,在这种简单的环境下,固定阈值的二值化效果比大津法好。另外,因为我们的车道线偏蓝色,我们选择提取图像的R通道进行二值化。检测效果如图: ![车道线内侧点提取效果展示](doc/lane_detect.jpg) 运动控制部分相对较为复杂,我们只采用了一个简单的逻辑,效果还可以。 ### 目标检测 识别并定位摄像头图像中的各类常见物体。 ![目标检测效果展示](doc/object_detection.gif) 主程序为main_object_detection.py,其调用了[TensorFlow Object Detection API](https://github.com/tensorflow/models/tree/master/research/object_detection),使用了训练好的的SSDLite目标检测模型,在树莓派端进行目标检测 。 TensorFlow安装方法及TensorFlow Object Detection API配置方法可以完全参考此文档:[EdjeElectronics/Tutorial to set up TensorFlow Object Detection API on the Raspberry Pi](https://github.com/EdjeElectronics/TensorFlow-Object-Detection-on-the-Raspberry-Pi#tutorial-to-set-up-tensorflow-object-detection-api-on-the-raspberry-pi) 或者TensorFlow Object Detection API可以直接clone这位的 [xyc2690/Raspberry_ObjectDetection_Camera](https://github.com/xyc2690/Raspberry_ObjectDetection_Camera),可以不用配置TensorFlow Object Detection API,下载即用。 我们使用的SSDLite模型主要优点是运行速度快、占用内存小,适合在树莓派端进行运算。据我们测试,帧率大概为0.8帧/s。我们使用的是树莓派3,如果是更新的型号,速度会更快一点。 ### 网球追踪 基于摄像头,使小车追踪一个移动的网球,并与网球保持一定距离。 ![网球追踪效果](https://i.loli.net/2019/10/31/SpHzE7MBRfkr5aN.gif) 主程序在main_tennis_tracking.py中,网球追踪流程大概如下: * 网球检测 * 图像预处理 * 霍夫圆检测 [霍夫圆检测原理](https://github.com/Mingrui-Yu/Tutorials/blob/master/Rapberry_Pi/%E7%BD%91%E7%90%83%E8%BF%BD%E8%B8%AA%E6%8A%80%E6%9C%AF%E5%8E%9F%E7%90%86.md#%E9%9C%8D%E5%A4%AB%E5%9C%86%E6%A3%80%E6%B5%8B) * HSV域颜色检测 [HSV变换原理](https://github.com/Mingrui-Yu/Tutorials/blob/master/Rapberry_Pi/%E7%BD%91%E7%90%83%E8%BF%BD%E8%B8%AA%E6%8A%80%E6%9C%AF%E5%8E%9F%E7%90%86.md#hsv%E5%8F%98%E6%8D%A2) * 运动控制 * 运动决策 * 电机控制 实验显示: 在不同光照条件下,网球的色调(H)基本上保持一致,范围大致在25至50 (OpenCV范围),在可靠明亮的光照条件下,范围大致在30至40。 网球检测的程序在detect_new.py中,具体流程如下: * 关注区域裁切:裁掉不可能出现网球的区域 * 高斯滤波:去除一定噪声 * 霍夫圆检测:检测出图像中所有可能存在的圆(视频中的绿色圆) * 针对每个检测出的圆的内切正方形: * RGB to HSV * 利用HSV域计算符合网球颜色的像素点数目 * 统计上述像素点数目占比 * 选出占比最大的圆,若其占比大于设定阈值,则认为是网球(视频中的红色圆) ![网球检测效果](https://i.loli.net/2019/10/31/OEKz3HRPcVj1ydQ.gif) 经测试,帧率大概在15帧/s。 运动控制的程序在main_tennis_tracking.py中,具体流程如下: * 移动平均:对检测得网球位置进行移动平均,减小误差 * 决策:根据当前网球相对于小车的位置,决策下一步的动作 * 根据网球x坐标决策转向动作 * 根据网球半径r决策前进后退动作 * 控制:根据决策结果,控制小车电机输出 目前存在的问题: * 我们使用的小车是4电机四驱差速转向小车,但在没有细致调教的差速控制算法的情况下,这样的配置使得在小车在转弯的时候存在较大的滑动摩擦(a skidding turn),所以转向时小车存在一个“最低启动速度”,当PWM的占空比小于一定值时,小车由于摩擦力的原因无法真的转起来,在原地“蹩着”,所以要小车转起来,只能给一个相对大的速度,这样就很容易转向过度。 * 同时,由于摩擦力,小车在转向时也存在明显的车身抖动,使得转向时拍摄的图像发飘发糊,导致此时网球检测得效果也收到影响,进一步影响了转向追网球的准确性。 * 网球检测的效果受光照的影响还是挺大的,白天光照充足的环境下(白天室外)效果会好很多。 ## 功能实现(使用教程) ### 自动避障 在树莓派终端中输入: ``` cd PythonCode python3 main_obstacle_avoidance.py ``` ### 实时图像传输 树莓派发送图像,在树莓派终端输入: ``` cd PythonCode python3 camera.py ``` 同时,如果想在PC端接收图像,在PC终端输入: ``` cd PythonCode python3 pc_receiver.py ``` NOTICE:camera.py和pc_receiver.py均需要根据具体情况配置HOST和POST: * 二者中的HOST均为PC在此WiFi网络下的IP地址(通过ifconfig查看) * 二者的PORT设置为同一个端口号就可以(eg:8000)。 ### 视觉车道循迹 在树莓派终端输入: ``` cd PythonCode python3 main_lane_tracking.py ``` 如果想在PC端接收车道检测图像,则在PC终端输入: ``` cd PythonCode python3 pc_receiver.py ``` ### 目标检测 在树莓派终端中输入: ``` cd PythonCode python3 main_object_detection.py ``` 如果想在PC端接收图像,则在PC终端输入: ``` cd PythonCode python3 pc_receiver.py ``` NOTICE:Tensorflow Object Detection API 和 ssdlite模型并未上传至此仓库,需要自行安装。二者的安装和配置方法请参考此文档:[EdjeElectronics/Tutorial to set up TensorFlow Object Detection API on the Raspberry Pi](https://github.com/EdjeElectronics/TensorFlow-Object-Detection-on-the-Raspberry-Pi#tutorial-to-set-up-tensorflow-object-detection-api-on-the-raspberry-pi) ; 或者TensorFlow Object Detection API可以直接clone这位的 [xyc2690/Raspberry_ObjectDetection_Camera](https://github.com/xyc2690/Raspberry_ObjectDetection_Camera),可以不用配置TensorFlow Object Detection API,下载即用。 ### 网球追踪 在树莓派终端输入: ``` cd PythonCode python3 main_tennis_tracking.py ``` 如果想在PC端接收网球检测图像,则在PC终端输入: ``` cd PythonCode python3 pc_receiver.py ``` ## Notes [All tutorials on Raspberry-Pi | GitHub](https://github.com/Mingrui-Yu/Tutorials/tree/master/Rapberry_Pi) * [创建wifi热点&开启SSH](https://github.com/Mingrui-Yu/Tutorials/blob/master/Rapberry_Pi/%E5%88%9B%E5%BB%BAwifi%E7%83%AD%E7%82%B9%26%E5%BC%80%E5%90%AFSSH%26putty%E8%BF%9E%E6%8E%A5.md#pi3-%E5%88%9B%E5%BB%BAwifi%E7%83%AD%E7%82%B9--%E5%BC%80%E5%90%AFssh--putty%E8%BF%9E%E6%8E%A5) * [相机&opencv-python](https://github.com/Mingrui-Yu/Tutorials/blob/master/Rapberry_Pi/%E7%9B%B8%E6%9C%BA%26opencv_python.md#%E5%9C%A8%E6%A0%91%E8%8E%93%E6%B4%BE%E4%B8%8A%E5%AE%89%E8%A3%85%E5%9F%BA%E4%BA%8Epython%E7%9A%84opencv) * [更换下载源](https://github.com/Mingrui-Yu/Tutorials/blob/master/Rapberry_Pi/%E6%9B%B4%E6%8D%A2%E4%B8%8B%E8%BD%BD%E6%BA%90.md#%E5%88%87%E6%8D%A2%E5%88%B0%E5%9B%BD%E5%86%85%E7%9A%84apt-get%E4%B8%8B%E8%BD%BD%E6%BA%90) * [TensorFlow相关](https://github.com/Mingrui-Yu/Tutorials/blob/master/Rapberry_Pi/%E5%AE%89%E8%A3%85tensorflow.md#tensorflow-%E5%AE%89%E8%A3%85) * [直流电机 & H桥 & PWM](https://github.com/Mingrui-Yu/Tutorials/blob/master/Rapberry_Pi/%E7%9B%B4%E6%B5%81%E7%94%B5%E6%9C%BA%E7%9B%B8%E5%85%B3.md#%E7%9B%B4%E6%B5%81%E7%94%B5%E6%9C%BA%E7%9B%B8%E5%85%B3%E7%9F%A5%E8%AF%86) * [超声波传感器相关](https://github.com/Mingrui-Yu/Tutorials/blob/master/Rapberry_Pi/%E8%B6%85%E5%A3%B0%E6%B3%A2%E4%BC%A0%E6%84%9F%E5%99%A8.md#%E8%B6%85%E5%A3%B0%E6%B3%A2%E4%BC%A0%E6%84%9F%E5%99%A8%E7%9B%B8%E5%85%B3)