机器谱 发表于 2023-1-9 13:55:50

开源项目分享 | 基于机器视觉的移动消防机器人(二)

本帖最后由 机器谱 于 2023-1-9 13:55 编辑

本文素材来源于北方民族大学 机电工程学院
作者:牟义达、黄瑞翔、李涛
指导老师:田国禾、张春涛


一、软件设计

1. 总系统软件流程图
       为了实现消防功能,对软件进行系统设计。根据机器人要实现的功能进行逐一设计,设计完之后再将其整合到一起,整合之后的就是总的设计,下面就是总设计的流程图。总流程图如下:

      小车的整个功能流程如上图所示。小车先前行一段距离,之后停下来检测火源,若检测到火源,则记下火源的位置,然后命令灭火装置抵达火源处进行消防作业。火灭之后小车再度前行,之后再循环前面操作。

2. 各个功能的流程图(1)机器人自主行走的流程

      自主行走功能的实现主要是驱动电机的转动,电机附于控制板。当控制板控制电机的两个引脚电压不同且电压差达到电机的工作电压时,电机就朝一个方向转动,从而达到驱动机器人小车的目的。控制控制板对应电机的引脚电压的流程图如上,即开始时让引脚有个电压差,0.5秒后让引脚电压持平(电机停止转动),这时看检测模块的状态,若火已被检测到,则引脚电压继续持平,若火已灭则引脚会有电压差。
(2)检测功能的流程       检测的流程为:舵机1先定于水平位置,驱动轮驱动小车前行,小车停下时舵机1、2开始范围内摆动。因为传感器安装于舵机1、2控制的杆上,所以当舵机1、2范围内摆动时传感器可以在该范围内进行火源检测。若在该范围内检测到火时,则舵机1、2摆动完成之后会定位到火源的位置,此时灭火装置开启;灭火装置工作一段时间后再进行检测,若还能检测到火源,则舵机1、2还是保持原位并开启灭火装置提供的灭火功能。若未检测到火源,则舵机循环开始的行程。

(3)灭火功能流程

      消防机器人小车的灭火流程不是很复杂,灭火装置就是由小马达和风扇叶组合而成的,当马达转动时风扇开启,所以只需控制马达的转动就能控制灭火装置的灭火功能。当检测到火时控制马达转动,当检测不到火时控制马达停止,这也就能达到控制灭火功能的要求。
二、实验验证
1. 自主行走功能验证实验目的:让机器人小车行驶500ms后停500ms,循环重复。实验器材:计算机、消防机器人小车。实验步骤:设计自主行走功能检验程序;将双轴驱动直流电机连接于控制板上9、10引脚上;编译、烧录控制程序;锂电池插再控制板上给其供电;打开控制板电源开关;观察小车驱动轮的状态。实验结果:小车驱动轮在控制板电源开启时转动,转动500ms后停下,之后往复循环。实验结论:小车能按照指定功能执行操作,具备自主行走能力。

2. 火源检测功能验证实验目的:让机器人小车检测火源并使机器人灭火装置定位至火源处。实验器材:计算机、消防机器人小车、打火机、蜡烛一根。实验步骤:设计火源检测功能检验程序;将舵机1、2分别连接于控制板的3、8引脚上;编译、烧录验证程序;控制板连接锂电池;在光照度不强的场地点燃蜡烛并将蜡烛固定摆放;将消防机器人小车与距蜡烛保持合适距离(因光照强度的不同传感器的有效触发距离不同),可以不断改变蜡烛的摆放位置;打开控制板开关;观察小车检测装置的运行状态。实验结论:小车的检测装置在一定范围内检测,范围内检测完成之后若中途检测到火源则会定位到火源处。消防机器人小车具备检测火源的功能。

3. 灭火功能验证实验目的:使灭火装置对准火源,开启灭火装置,检验是否能完成灭火工作。实验器材:计算机、消防机器人小车、蜡烛一根、打火机。实验步骤:设计灭火功能检验程序;将灭火装置连接于控制板上;编译、烧录检验程序;连接锂电池于控制板上;点燃蜡烛并固定摆放;使灭火装置对准火源并保持合适距离;打开控制板电源;观察蜡烛是否被吹灭。实验结论:灭火装置开启时蜡烛很快被吹灭,消防小车灭火装置具备灭火功能。

4. 消防机器人小车功能整体验证实验目的:检测消防小车能否按照所设计的消防程序进行消防作业。实验器材:计算机、消防机器人小车、蜡烛一根、打火机一个。实验步骤:将设计好的总程序编译、烧录至控制板;将驱动直流电机、两个舵机、灭火装置分别接线于控制板;点燃蜡烛并固定摆放于合适位置;将消防机器人小车放置距离蜡烛1m处,开启控制板电源;观察消防机器人的运行状态。实验结论:消防机器人小车能完成消防作业,程序设计合理。

三、程序代码

1.消防机器人控制程序
#include <Servo.h>

Servo myservo1;                        //定义两个舵机

Servo myservo2;

int pos1 = 0;                              //舵机初始角度

int pos2 = 0;

const int buttonPin = A2;                  // 传感器端口设为A2

int buttonState = 0;                         //设一个转换库

void setup()

{

    Serial.begin(9600);                     //初始化串口

    myservo1.attach(3);                      //舵机接线端口设为3和8

    myservo2.attach(8);

    pinMode(5,OUTPUT);                  //定义5、6、9、10、11为输出端口

    pinMode(6,OUTPUT);

    pinMode(9,OUTPUT);

    pinMode(10,OUTPUT);

   

}


void loop()

{

buttonState = digitalRead(buttonPin);          //读取A0的电平并存于转换库里面

myservo1.write(150);                     //舵机1定在150度

Serial.println(" 舵机1定在150度")

delay(3000);

digitalWrite(5,1);                           //车四个轮子驱动前进

digitalWrite(6,0);

digitalWrite(9,HIGH);

digitalWrite(10,HIGH);


delay(500);                              //0.5秒延迟

digitalWrite(5,1);                           //车停下来

digitalWrite(6,1);

digitalWrite(9,HIGH);

digitalWrite(10,HIGH);

Serial.println(" 舵机2开始正摆动");

for(pos1 = 120; pos1 < 170; pos1 += 10)         // 舵机1开始正摆动

    {

   myservo1.write(pos1);

   for(pos2 = 20; pos2 < 160; pos2 += 1)      // 舵机2开始正摆动

      {                                 

         myservo2.write(pos2);

         if(digitalRead(buttonPin))             //如果火焰传感器触发(A0被至1),将pos2此时的值记下并保存于buttonState中

            {

             buttonState=pos2;

             duoji1jiaodu=pos1;

             }

         Serial.println(buttonState);            //串口监视器返回buttonState值

         delay(60);                        

      }

   }

   

   if(buttonState)                              //非零即为真

   {

      Serial.println(" 舵机转至火焰处");

      myservo1.write(duoji1jiaodu);

      myservo2.write(buttonState);

      delay(3000);

      while(digitalRead(buttonPin))            //检测到火时一直开启风扇

          {

            Serial.println(" 风扇一直开");

            digitalWrite(9,HIGH);

            digitalWrite(10,LOW);

            delay(3000);

         }

       Serial.println(" 火灭了,风扇关了,小车前进");

       delay(500);                           //停0.5秒

       digitalWrite(5,1);                      //车停下来

       digitalWrite(6,1);

       digitalWrite(9,HIGH);

       digitalWrite(10,HIGH);

   

      }

      

   else

   {

       digitalWrite(5,1);                      //车四个轮子驱动前进

       digitalWrite(6,0);

       delay(500);                           //停3秒

       digitalWrite(5,1);                      //车停下来

       digitalWrite(6,1);

       Serial.println(" 舵机1 2开始负摆动");

       for(pos1 = 170; pos1>120; pos2 .= 10)      //舵机1开始负摆动

         {

          for(pos2 = 160; pos2>20; pos2 .= 1)   //舵机2开始负摆动

             {                                 

            myservo2.write(pos2);

            if(digitalRead(buttonPin))          //如果火焰传感器触发

(A0被至1),将pos2此时的值记下并保存于buttonState中

               {

                  buttonState=pos2;

                  duoji1jiaodu=pos1;

                           

               }

            Serial.println(buttonState);

            delay(60);                     

            }

          if(buttonState)                        //非零即为真

            {

             myservo1.write(duoji1jiaodu);

             myservo2.write(buttonState);

             delay(3000);

             while(digitalRead(buttonPin))         //检测到火时一直开启风扇

                  {

                   digitalWrite(9,HIGH);

                   digitalWrite(10,LOW);

                   delay(3000);

                  }

             Serial.println(" 火灭了,风扇关了,小车前进");   

             delay(500);                        //停3秒

             digitalWrite(5,1);                     //车停下来

             digitalWrite(6,1);

             digitalWrite(9,HIGH);

             digitalWrite(10,HIGH);

         

             }

         }

   }

}
2. 小车自主行走功能验证程序代码void setup()

{

pinMode(9,OUTPUT);            //定义9、10引脚为输出引脚

pinMode(10,OUTPUT);

}


void loop()

{

digitalWrite(9,HIGH);            //9引脚输出高电平

digitalWrite(10,LOW);         //10引脚输出低电平

delay(500);                  //延迟0.5秒

digitalWrite(9,HIGH);         //9、10引脚输出高电平

digitalWrite(10,HIGH);


}


检测功能验证程序代码

#include <Servo.h>

Servo myservo1;               //定义两个舵机

Servo myservo2;

int pos1 = 0;                  //舵机初始角度

int pos2 = 0;

const int buttonPin = A0;   // 传感器端口设为A0

int buttonState = 0;          //设一个转换库

void setup()

{

    myservo1.attach(3);      //舵机接线端口设为3和8

    myservo2.attach(8);

   

}


void loop()

{

buttonState = digitalRead(buttonPin);   //读取A0的电平并存于转换库里面

myservo1.write(150);               //舵机1定在150度

for(pos2 = 20; pos2 < 160; pos2 += 1)   // 舵机2开始正摆动

   {                                 

      myservo2.write(pos2);

      if(digitalRead(buttonPin))   //如果火焰传感器触发(A0被至1),将pos2此时的值记下并保存于buttonState中

         {

          buttonState=pos2;

          }

      delay(60);                        

   }

   

if(buttonState)                     //非零即为真

      {

       myservo2.write(buttonState);

      }

   

else

   {

      for(pos2 = 160; pos2>20; pos2 .= 1) //舵机2开始负摆动

         {                                 

          myservo2.write(pos2);

          if(digitalRead(buttonPin))      //如果火焰传感器触发(A0被至1),将pos2此时的值记下并保存于buttonState中

          buttonState=pos2;         

          delay(60);                     

          }

      if(buttonState)                     //非零即为真

      {

         myservo2.write(buttonState);

         

         }

   }

}
3. 灭火功能验证程序代码void setup()

{   

    pinMode(5,OUTPUT);          //定义5、6为输出端口

    pinMode(6,OUTPUT);   

}

void loop()

{

    digitalWrite(5,1);            //5引脚输出高电平

    digitalWrite(6,0);            //6引脚输出低电平

}

想了解更多机器人开源项目资料请关注 机器谱网站 https://www.robotway.com


页: [1]
查看完整版本: 开源项目分享 | 基于机器视觉的移动消防机器人(二)