机器人制作开源方案 | 森林管理员

news2025/2/8 23:35:48

​作者:李佳骏、常睿康、张智斌、李世斌、高华耸

单位:山西能源学院

指导老师:赵浩成、郜敏

1. 研究背景

      森林作为地球上可再生自然资源及陆地生态的主体,在人类生存和发展的历史中起着不可代替的作用,它不仅能提供国家建设和人民生活所需的木材及林副产品,而且还肩负着释放氧气调节气候环境,涵养水源、保持水土、防风固沙、美化环境、净化空气、减少噪音及旅游保健等多种使命,同时森林还是农牧业稳产高产的重要条件。然而,森林火灾是森林最危险的敌人,也是林业最可怕的灾害,也会给森林带来最有害、具有毁灭性的后果。森林火灾不只是烧毀片片森林,伤害林内动物,而旦还降低森林的更新能力,引起土壤的贫瘠和破坏森林涵养水源的作用,甚至号致生态环境失去平衡。2019年3月30日,四川省凉山州木里县就曾经发生过一次非常严重的森林火灾。2019年3月30日是一个雨天,木里县喇嘛寺沟附近下午5点左右出现了雷雨天气,虽然只是一次持续了30秒左右的阵雨,但是隆隆雷声却一直回荡在天空,不绝于耳。下午6点时一场森林火灾在山上悄然而至,起火点位于海拔3800余米的山上,山中地形复杂,遍布沟壑,无论是交通还是通讯情况都非常不好,消防官兵难以迅速赶往现场进行救援。经过相关部门得知消息后初步判断本次火灾的原因,可能是由于之前降兩时的雷击导致,多个起火点都位于山崖上,火场平均海拔高达4千米。31日下午,689位救火人员带着各种设备登山,前往海拔4000余米的原始森林开展救火工作,由于当日风向不定,风力风向突变导致山火爆燃形成一个巨大的火球。救火人员兵分两路进行避险,其中一路安全撤离,另一路的27位森林消防指战员和三名地方救火人员就此和其他人失去了联系。4月2日早晨六点30分,田火山山上的明火终于被扑灭。而制作山林隔离带是有效制止森林大火蔓延的的有效方式,且该方面大多是通过人工下地来完成的,所以我们设计了一款可通过远程遥控来实现砍伐、运输一体化的全地形机器人,减少人工的需求量和危险性。同时,目前生活中的伐木大多由人工实地操作,我们的作品也可以代替其完成系统化的作业。

2. 主要功能

      本小组作品的主要功能有在大火发生时,及时进入火场中,对还未涉及到的地域进行砍伐树木,降低火灾面积。本小车为全地形小车,可以适应森林中的各种地形,如山坡、地坑等等。小车一侧设有抓夹,在另一侧砍伐完树木后抓夹可以及时将树枝抓起放到车后部,最终由小车将其带出森林。在救援的同时小车前部设有摄像头以及湿度传感器,实时监控并记录火灾情况。本作品不仅可以用作在森林防护中制作隔离带的一体化工作,也可以用作日常生活中做伐木一体机器人使用。

3. 场景调研

      森林火灾的起因主要有两大类:人为火和自然火。人为火包括:生产性火源(农、林、牧业生产用火,林副业生产用火,工矿运输生产用火等)、非生产性火源(野外吸烟、做饭、烧纸、取暖等)、故意纵火。自然火包括:雷电火、自燃等。由于我国的森林火灾中,由吸烟、烧荒和上坟烧纸引起的火灾占了绝大多数,所以我们小组场地模拟森林火灾的起因为烧荒。在实际的地形中会存在山坡和小断层,我们小组在模拟时,模拟机器人爬小山坡和爬小台阶(断层)。同时,模拟了砍伐树木的过程,再砍伐完后,车另一侧的抓夹会将树木夹起搬运出森林。在进行就救援以及砍伐树木时,车前的摄像头可进行实时监控,可记录下在砍伐树木时周遭的实时动态,同时还有湿度传感器的实时监测。

4. 机器人本体技术路线说明

      ① 机械结构:整体车身分为两部分,前端车体运用柔性结构,并采用履带式车轮,后部采用传统轮胎,有着很好的抓地力。车体大致结合军用坦克的履带的优越性并结合实际,改装了后置轮胎,使得前后轮可以通过配合,从而顺利翻越一些工作途中所遇到的障碍。

      ② 驱动系统:该车加装了6个双直流电机共同驱动,六个电机同时驱动,为小车提供了足够的动力,减少了动力的损失,为通过障碍物提供了足够的动力条件,电锯有单舵机制作的机械臂和电机控制的电锯体实现横向自由伸展,砍伐树木。机械爪由两个舵机控制的机械臂和单舵机控制的爪体构成,可实现横向伸展并调整爪子的摆动,实现抓取。

      ③ 控制系统:主板采用了Basra主控板,通过ESP8266Wi-Fi模块与电脑连接实现远程实时无限操作,通过摄像头、温湿度传感器来实时反馈现场情况,为人们的勘测和救援提供信息帮助。

      ④ 感知系统:车体全程操作由人工在远程通过WiFi模块实时操作,在车体的前方和中段均装有摄像头,前部摄像头可帮我我们锁定目标树木的方向,也可以规避障碍物,在侧端的摄像头可对目标数目进行定位,当其进入合适位置后进行砍伐和搬运。在车的顶部同时也装配了温湿度传感器,对周围环境进行监控,并及时反馈,为人工救援行动提供保障。

5. 示例程序

#include <Servo.h>

int _ABVAR_1_data = 0 ;

int in1 = 5;

int in2 = 6;

int in3 = 9;

int in4 = 10;

int in5 = 12;

int SERVO_SPEED=20;                                        //定义舵机转动快慢的时间

int ACTION_DELAY=200;                                      //定义所有舵机每个状态时间间隔

Servo myServo[4];

int f = 50;                                                     //定义舵机每个状态间转动的次数,以此来确定每个舵机每次转动的角度

int servo_port[4] = {3,4,7,8};                            //定义舵机引脚

int servo_num = sizeof(servo_port) / sizeof(servo_port[0]);     //定义舵机数量

float value_init[4] = {10, 40, 20, 40};                //定义舵机初始角度

//10, 110, 20, 40chu    100, 110, 60, 30   kaishi     100, 40, 60, 30zhua     100, 40, 40, 30qi    10, 40, 60, 30weizhi   

//float value_init[6] = {10, 130, 60, 30};                //定义舵机初始角度

//float value_init[6] = {0, 40, 40, 40};

void setup()

{

Serial.begin(9600);

pinMode(in1, OUTPUT);

  pinMode(in2, OUTPUT);

  pinMode(in3, OUTPUT);

  pinMode(in4, OUTPUT);

    pinMode(in5, OUTPUT);

 

       for(int i=0;i<servo_num;i++){

    ServoGo(i,value_init[i]);

  }

}

void ServoStart(int which)

{

  if(!myServo[which].attached())myServo[which].attach(servo_port[which]);

  pinMode(servo_port[which], OUTPUT);

}

void ServoStop(int which)

{

  myServo[which].detach();

  digitalWrite(servo_port[which],LOW);

}

void ServoGo(int which , int where)

{

  if(where!=200)

  {

    if(where==201) ServoStop(which);

    else

    {

      ServoStart(which);

      myServo[which].write(where);

    }

  }

}

void servo_move(float value0, float value1, float value2, float value3)

{

  float value_arguments[] = {value0, value1, value2, value3};

  float value_delta[servo_num];

  for(int i=0;i<servo_num;i++)

  {

    value_delta[i] = (value_arguments[i] - value_init[i]) / f;

  }

  for(int i=0;i<f;i++)

  {

    for(int k=0;k<servo_num;k++)

    {

      value_init[k] = value_delta[k] == 0 ? value_arguments[k] : value_init[k] + value_delta[k];

      /**************************串口查看输出*****************************/

//      Serial.print(value_init[k]);

//      Serial.print(" ");

    }

//    Serial.println();

      /**************************串口查看输出*****************************/

 

    for(int j=0;j<servo_num;j++)

    {

      ServoGo(j,value_init[j]);

    }

    delay(SERVO_SPEED);

  }

  delay(ACTION_DELAY);

}

void loop()

{

/*   servo_move(10, 40, 20, 40);

     delay(500);

       servo_move(100, 20, 20, 40);

     delay(500);

     servo_move(100, 110, 20, 40);

     delay(500);

     servo_move(100, 110, 60, 40);

     delay(500);   

    servo_move(100, 40, 60, 40);

     delay(500);

  servo_move(10, 40, 60, 40);

   delay(500);

  servo_move(10, 40, 20, 40);*/

_ABVAR_1_data = Serial.read() ;

if (( ( _ABVAR_1_data ) == ( 1 ) ))

{

       analogWrite(in1, 0);                         

      analogWrite(in2, 0);

      analogWrite(in3, 0);

      analogWrite(in4, 160);

      delay (10);

}

if (( ( _ABVAR_1_data ) == ( 2 ) ))

{

  for(int i=0;i<10;i++)

{

    analogWrite(in1, 160);

      analogWrite(in2, 0);

      analogWrite(in3, 0);

      analogWrite(in4, 0);

      delay (10);

}

}

if (( ( _ABVAR_1_data ) == ( 12 ) ))

{     

   for(int i=0;i<10;i++)

{

  servo_move(190, 40, 20, 130);

  analogWrite(in1,150);

      analogWrite(in2,0);     

        analogWrite(in4,150);

      analogWrite(in3,0);

    delay (1000);

}

}

if (( ( _ABVAR_1_data ) == ( 3 ) ))

{     

   

  analogWrite(in1,150);

      analogWrite(in2,0);     

        analogWrite(in4,150);

      analogWrite(in3,0);

    delay (1000);

}

if (( ( _ABVAR_1_data ) == ( 0 ) ))

{       analogWrite(in1,0);

      analogWrite(in2,0);     

        analogWrite(in4,0);

      analogWrite(in3,0);

}

if (( ( _ABVAR_1_data ) == ( 4) ))   //jixiebi1

{     

servo_move(10, 40, 40, 130);

delay(500);

  delay(500);

   delay(500);

  analogWrite(in5, 250);

   delay(500);

}

if (( ( _ABVAR_1_data ) == ( 5) ))   //jixiebi1

{     

servo_move(10, 40, 20, 60);

     delay(500);

  analogWrite(in5, 0);

}

if (( ( _ABVAR_1_data ) == ( 7) ))   //10, 110, 20, 40chu    100, 110, 60, 30   kaishi     100, 40, 60, 30zhua     100, 40, 40, 30qi    10, 40, 60, 30weizhi   

{     

servo_move(100, 110, 60, 30);

     delay(500);

 

}

if (( ( _ABVAR_1_data ) == ( 8) ))   //qi

{     

servo_move(100, 40, 60, 30);

     delay(500);

 

}

if (( ( _ABVAR_1_data ) == ( 9) ))   //fan

{     

servo_move( 100, 40, 40, 30);

  delay(1000);  

 

}

if (( ( _ABVAR_1_data ) == ( 10) ))   //fan

{     

servo_move( 10, 40, 60, 30);

  delay(1000);  

 

}

if (( ( _ABVAR_1_data ) == ( 11) ))   //fan

{   

    servo_move(10, 40, 20, 40);

     delay(500);

       servo_move(100, 20, 20, 40);

     delay(500);

     servo_move(100, 130, 20, 40);

     delay(500);

     servo_move(100, 130, 50, 40);

     delay(500);   

    servo_move(100, 40, 50, 40);

     delay(500);

  servo_move(10, 40, 50, 40);

   delay(500);

  servo_move(10, 40, 20, 40);

}

}

6. 创新点

      小车行进结构利用“太极”式刚柔结合进行翻越障碍。当小车遇到有一定角度的倾斜坡的时候,此时小车的刚性材料组成的车轮即可派上用场,通过调整履带的旋转自由度,使得小车在上坡的过程中不会发射管前倾和后倾。在小车遇到有断崖(台阶)的地面环境时,其柔性材料做成的车轮,经过调整前轮的自由度和前轮和后轮之间的距离,可以做出俯仰抬头的动作,从而轻松爬上断崖(台阶}。与此同时,俩种不同材料组成的车轮,也解决了在移动过程中出现的打滑问题,使小车的稳定性更高。其次,小车的机械臂可以180°进行旋转,不仅使小车在工作时候可接触的范围更广,还减小了车的体积,从而加快了小车的速度,车身在此期间也可以保持到最佳的位置。在此期间,同时可以利用小车体积小的优势,可以顺利通过小的隧道进行工作。最后,我们设计的小车使其重心集中在了整个小车的最中心,减少了了在通过障碍工作途中造成小车前倾或者后倾,从而翻车的情况,加强了小车的稳定性。

7. 作品难点

      ① 本作品在左右两侧分别装有不同的机械结构,应对其进行有效合理的位置和结构设计,保证其相对应与其他传感器的配合。

      ② 小车在运行过程中需通过不同的障碍结构,而由于车身较小,故掌握小车在登台阶和上坡时的平衡很是关键,防止侧翻。故我们在进行上(下)坡(台阶)会将左右机械臂摆至前(后)进行平衡。

      ③ 在小车砍到设计的隔离带树木后,放在车后方拉出时,怎么样去寻找最合适的路线去拉走树木,从而防止其他树木在路途中阻挡砍到的树木撤离火源。

更多详情请见 :【S043】森林管理员

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1335988.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

比宜德停业,奥乐齐死磕,硬折扣该怎样长硬不衰?

作者 | 楚文龙 来源 | 洞见新研社 刚刚过去的周末&#xff0c;让零售行业的从业者神经紧绷。因为&#xff0c;12月23日多个信源曝出&#xff0c;社区硬折扣超市比宜德已公告于12月22日起暂停营业。 作为中国第一家&#xff0c;也是唯一一家规模最大的硬折扣社区连锁店零售商&…

FLStudio21中文版水果编曲软件好用吗?如何下载最新版本

FL Studio21版是一款在国内非常受欢迎的多功能音频处理软件&#xff0c;我们可以通过这款软件来对多种不同格式的音频文件来进行编辑处理。而且FL Studio 21版还为用户们准备了超多的音乐乐器伴奏&#xff0c;我们可以直接一键调取自己需要的音调。 FL Studio21版不仅拥有非常…

leetcode——打家劫舍问题汇总

本章汇总一下leetcode中的打家劫舍问题&#xff0c;使用经典动态规划算法求解。 1、梦开始的地方——打家劫舍&#xff08;★&#xff09; 本题关键点就是不能在相邻房屋偷东西。 采用常规动态规划做法&#xff1a; 根据题意设定dp数组&#xff0c;dp[i]的含义为&#xff1a…

【WPF.NET开发】创建样式

本文内容 创建样式隐式应用样式显式应用样式以编程方式应用样式扩展样式TargetType 属性与 x:Key 属性之间的关系 使用 Windows Presentation Foundation (WPF)&#xff0c;可以使用自己的可重用样式自定义现有控件的外观。 可以对应用、窗口和页面全局应用样式&#xff0c;也…

【自定义磨砂动态背景】前端及pyqt6实现

如何实现一个自定义的磨砂动态背景呢&#xff1f; 这种效果看起来特别的高端&#xff0c;很新颖美观。 具体的效果可以看这里的演示&#xff1a;https://www.bilibili.com/video/BV1zj411H7wd/ 其实原理就是底层有多个多彩多边形在移动&#xff0c;然后再盖上一层模糊滤镜。 前…

【DevOps 工具链】搭建 项目管理软件 禅道

文章目录 1、简介2、环境要求3、搭建部署环境3.1. 安装Apache服务3.2. 安装PHP环境&#xff08;以php7.0为例 &#xff09;3.3. 安装MySQL服务 4、搭建禅道4.1、下载解压4.2、 配置4.2.1、 启动4.2.2、自启动4.2.3、确认是否开机启动 5、成功安装 1、简介 禅道是国产开源项目管…

React Router有几种模式?实现原理?

面试官&#xff1a;说说React Router有几种模式&#xff1f;实现原理&#xff1f; 一、是什么 在单页应用中&#xff0c;一个web项目只有一个html页面&#xff0c;一旦页面加载完成之后&#xff0c;就不用因为用户的操作而进行页面的重新加载或者跳转&#xff0c;其特性如下&a…

C++设计模式 #7 工厂方法(Factory Method)

“对象创建”模式 通过“对象创建”模式绕开new&#xff0c;来避免对象创建&#xff08;new&#xff09;过程中所导致的紧耦合&#xff08;依赖具体类&#xff09;&#xff0c;从而支持创建的稳定。它是接口抽象之后的第一步工作。 动机 在软件系统中&#xff0c;经常面临着创…

Flowable-升级为7.0.0.M2-第一节

目录 升级jdk升级springboot到3.1.3升级数据库连接池druid-spring-boot-3-starter到1.2.20升级mybatis-plus到3.5.3.2升级flowable到7.0.0.M2 最近有些读者一直问flowable如何升级到7.0.0.M2&#xff0c;接下来我就一步步的把flowable升级到7.0.0.M2 升级jdk flowable7.x采用的…

【数据结构】LRU缓存的简单模拟实现(leetcode力扣146LRU缓存)

文章目录 一、定义二、LRU模拟实现二、代码实现 一、定义 LRU是Least Recently Used的缩写&#xff0c;意思是最近最少使用&#xff0c;它是一种Cache替换算法。 Cache的容量有限&#xff0c;因此当Cache的容量用完后&#xff0c;而又有新的内容需要添加进来时&#xff0c; 就…

VScode远程连接服务器,Pycharm专业版下载及远程连接(深度学习远程篇)

Visual Code、PyCharm专业版&#xff0c;本地和远程交互。 远程连接需要用到SSH协议的技术&#xff0c;常用的代码编辑器vscode 和 pycharm都有此类功能。社区版的pycharm是免费的&#xff0c;但是社区版不支持ssh连接服务器&#xff0c;只有专业版才可以&#xff0c;需要破解…

ARM Cortex-A学习(1):GIC(通用中断控制器)详解

文章目录 1 Cortex-A核中断1.1 处理器模式1.2 IRQ模式 2 GIC的操作2.1 CPU Interface2.2 Distributor GIC(通用中断控制器, Generic Interrupt Controller)是一种用于处理中断的硬件组件&#xff0c;它的主要功能是协调和管理系统中的中断请求&#xff0c;确保它们被正确地传递…

前端项目重构的深度思考和复盘

摘要&#xff1a; 项目重构是每一家稳定发展的互联企业的必经之路, 就像一个产品的诞生, 会经历产品试错和产品迭代 一样, 随着业务或新技术的不断发展, 已有架构已无法满足更多业务扩展的需求, 所以只有通过重构来让产品“进化”, 才能跟上飞速发展的时代浪潮. 技术因素 早期…

【http】缓存协议

✨ 专栏介绍 在当今互联网时代&#xff0c;计算机网络已经成为了人们生活和工作中不可或缺的一部分。而要实现计算机之间的通信和数据传输&#xff0c;就需要依靠各种网络协议来进行规范和约束。无论是浏览网页、发送电子邮件还是进行在线交流&#xff0c;都离不开各种各样的网…

使用pytorch神经网络拟合计算模型

一. 内容简介 python调用百度翻译api&#xff0c;将中文论文翻译英文&#xff0c;并保留部分格式 二. 软件环境 2.1vsCode 2.2Anaconda version: conda 22.9.0 2.3数据文件 链接&#xff1a;https://pan.baidu.com/s/1csJOoErGyx77MW_FImVKjg?pwd1234 三.主要流程 3.…

@click 默认传递原生的事件对象

项目场景 [Day1] <template><div id"app"><h1>小黑记事本</h1><button click"handleClick">www</button><div class"head"><!-- 按键&#xff08;回车&#xff09;按下&#xff0c;出发add事件&…

MyBatis见解4

10.MyBatis的动态SQL 10.5.trim标签 trim标签可以代替where标签、set标签 mapper //修改public void updateByUser2(User user);<update id"updateByUser2" parameterType"User">update user<!-- 增加SET前缀&#xff0c;忽略&#xff0c;后缀…

uniapp创建/运行/发布项目

1、产生背景----跨平台应用框架 在移动端各大App盛行的时代&#xff0c;App之间的竞争也更加激烈&#xff0c;他们执着于让一个应用可以做多个事情 所以就应运而生了小程序&#xff0c;微信小程序、支付宝小程序、抖音小程序等等基于App本身的内嵌类程序。 但是各大App他不可…

解决ELement-UI三级联动数据不回显

目录 一.处理数据时使用this.$set方法来动态地设置实例中的属性&#xff0c;以确保其响应式。 二.检查数据格式是否正确 三.绑定v-if 确保每次执行 四.完整代码 一.处理数据时使用this.$set方法来动态地设置实例中的属性&#xff0c;以确保其响应式。 二.检查数据格式是否正确…

通过three.js玩转车展项目

1.项目搭建 1.1 创建文件夹 mkdir 文件名1.2 初始化package.json npm init -y1.3 安装打包工具并配置相关依赖 npm i parcel -d在package.json中打包路径和指令 1.4 安装three.js npm i three -d2.项目搭建 2.1 新建index.html&#xff0c;并再index.html引入car.js,在…