基于opencv树莓派的寻灯灭灯小车--第六届全国光电设计大赛智能车组(上)

这篇文章用来分享第六届全国光电设计大赛智能车组的源码,本次比赛的赛题如下:

 

 

 

 

本队小车:

 

 

本队比赛现场的部分视频:

http://www.iqiyi.com/w_19s2h925xd.html

 


 

本次比赛我们组采用树莓派+opencv+wiringpi的解决方案,编程语言是c++,借助QT开发

一、基本设计思路:

1.1、读取摄像头数据,将图像转为HSV(色调,饱和度,明度)颜色空间;

1.2、提取色调(H)和明度(V)通道,设置阈值,将图像二值化;

1.3、找到图像中最大的目标,并求出包围 该目标的矩形中心坐标;

1.4、根据pid算法,控制小车舵机转向和车速的高低,向目标点前进;

1.5、小车靠近目标一定距离后,会刹车减速,将红外接近开关调节到20cm触发,当检测到触发信号,小车停车,进入灭灯状态;

1.6、灭灯后小车会后退,并且绕圆旋转,直到找到下一个目标为止;

二、程序源码

2.0、声明三个全局变量

#include "mainwindow.h"
#include <QApplication>
#include <iostream>
using namespace std;
using namespace cv;
int m_timer=1;
int back = 1;
int speed = 0;

2.1、初始化IO口

    wiringPiSetup();           //初始化wiringpi
    pinMode(21,OUTPUT);        //21-27:post
    pinMode(22,OUTPUT);
    pinMode(23,OUTPUT);
    pinMode(24,OUTPUT);
    pinMode(25,OUTPUT);
    pinMode(26,INPUT);   //后方红外对管
    pinMode(27,INPUT);   //前方红外对管
    pinMode(28,INPUT);   //编码器
    softPwmCreate(1,22,100);          //挡板控制,25收回,5展开
    softPwmCreate(2,0,100);          //电机后退控制
    softPwmCreate(3,10,100);          //舵机控制
    softPwmCreate(4,25,100);          //电机前进控制

小车总共需要控制两个舵机,一个电机;

为了控制电机的速度及前进倒退,小车采用了mos管电机驱动(淘宝网买的),通过wiringpi输出两路软件pwm值控制电机的前进后退,舵机同样如此;

事实上wiringpi的软件pwm精度非常低,舵机调节范围为5~25,精度为1,对应舵机的0~180度;

电机调节范围为0~100;

这里的两个主要函数为

pinMode(25,OUTPUT);
softPwmCreate(1,22,100);

pinmode的第一个参数为树莓派的硬件io口,第二个参数为OUTPUT代表输出,INPUT代表输入,整行意思是将25口设置为输出模式

softpwmcreate第一个参数为io口,第二个参数为pwm输出的初始值,第三个参数为最大值

2.2、初始化摄像头并设置摄像头参数

    VideoCapture cap(0);
    cap.set(CV_CAP_PROP_FRAME_WIDTH,320);      //设置为320*240
    cap.set(CV_CAP_PROP_FRAME_HEIGHT,240);
    cap.set(CV_CAP_PROP_BRIGHTNESS,0.28 );    //设置亮度
    cap.set(CV_CAP_PROP_SATURATION,0.87);     //设置饱和度
    cap.set(CV_CAP_PROP_CONTRAST,0.53);       //设置对比度

饱和度亮度和对比度要根据现场情况进行调节

2.3、变量初始化

    float P = 0.04125;            //x轴pid算法中的p值
    float D = 0.009;              //x轴pid算法中的d值
    int pwm_x =0;
    int pwm_y = 50;
    float P_Y = w.m_p_y;            //y轴pid算法中的p值
    float D_Y = 0.05;               //y轴pid算法中的p值
    int ThisError_Y = 0;
    int LastError_Y = 0;
    int ThisError_x = 0;
    int LastError_x = 0;
    Mat frame;                   //用于承载摄像头的图像数据
    Mat edges;
    vector<Mat> channels;        //提取图像通道时用到
    vector<vector<cv::Point>> contours;    //目标坐标时用到
    vector<Vec4i> hierarchy;

2.4、线程的初始化

    w.workthread[1] = new WorkThread;
    w.workthread[1]->flag = 1;
    w.workthread[1]->close = 1;
    w.timethread[1] = new TimeThread;

workthread用来处理小车从将要接近目标到小车灭灯再到后退等一系列动作

timethread起到一个定时器和标志位改变的作用

 

至此,程序的初始化已经完成,接下来将会进入程序的while循环模块,我将在下一篇继续分享

  • 9
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值