当前位置: 首页 > news >正文

机器人制作开源方案 | 送餐机器人

作者:赖志彩、曹柳洲、王恩开、李雪儿、杨玉凯

单位:华北科技学院

指导老师:张伟杰、罗建国

一、作品简介

1. 场景调研

1.1项目目的

      近年来,全国多地疫情频发,且其传染性极高,食品接触是传播途径之一。疫情防控需要大量人员投入,常常出现人力紧张的情况,物资配送已经成为一大焦点问题。当前尚未有专门用于疫情送餐的机器人,因此开发一款自动化、智能化的送餐机器人,减少人员之间的接触,不仅可以提高工作效率、减轻人工劳动强度,而且可以有效减少交叉感染。

      在高校校园,学生外卖配送非常常见,但校门口琳琅满目的外卖往往被摊放在路边,甚至占用道路,造成交通混乱,因此急需一款高效便捷的送餐机器人来缓解这种情况。下图为校园人工送餐场景及外卖摊放情况。

疫情下校园送餐场景、学生点外卖场景

1.2市场调研

      我国送餐机器人行业发展起步较晚,大致经历了探索、起步、成长、爆发四个阶段。目前餐厅机器人距离真正意义上的智能化还存在技术门槛,在公共餐厅这种应用场景中,常规性的送餐、配菜需求机器人基本可以满足,但是功能比较单一。2020年疫情爆发之后,人们对于送餐机器人的需求很快上升,市场认可度不断上升,我国送餐机器人行业进入高速增长期,现在国内外疫情依然严重,送餐机器人的市场会还将不断提升扩大。

1.3项目意义

      减少人与人之间的接触是防止疫情扩散的有效手段,用机器人代替人工送餐,不仅可以代替耗时耗力的流程化作业,而且还可以避免工作人员在送餐过程中被感染的可能。而送餐机器人可以满足无接触送餐问题。

      送餐机器人开启了餐饮经营新模式,相较于传统的送餐方式,送餐机器人在疫情下减少人员接触,大大降低新冠传播率,提高食物配送效率,同时也可缓解因外卖造成的交通压力;送餐机器人对于餐厅价值有了很大的自主发挥空间,超越了传统餐饮消费的定义。

2. 创新点

2.1双工作模式

① 正常模式

      点餐者在与送餐机器人进行匹配的外卖App点餐后,送餐机器人到达指定地点,自助装取食物后,正常模式下灰度循迹传感器处于关闭状态,此时的机器人只基于终端路径来行进,利用超声波与红外避障对途中行人与障碍物避障,实现自助送餐。到达指定送餐地点后,当车身人体红外模块检测到点餐者接近时,解除安全锁定状态,装载食物的升降平台从保温箱中升起,点餐者取餐,完成一次送餐任务。

② 疫情模式

      在疫情爆发,学校处于静默期间时,送餐机器人可以通过灰度循迹传感器沿着工作人员设置的黑色送餐路径行走。送餐机器人利用超声波、红外避障等进行循迹与避障。到达指定送餐地点后,升降平台从保温装置升起食物,机械臂自动将食物放置在隔离人员房间门口,减少人员接触。

2.2高阻热保温箱

      采用质量轻、加工性好、致密度高、保温隔热效果好的聚氨酯泡沫包裹整个升降平台,达到阻热效果。保持食物原有温度,保证食物口感。

2.3数据实时显示

      机器人工作状态将在液晶显示屏右下角实时显示。小车底盘运行、机械臂与升降平台工作状态分别编号为1、2、3,正常工作状态分别为#,待机状态为*。与障碍物之间的距离间隔一秒在屏幕左下角显示。

      送餐信息实时显示在屏幕上方,时间为12:38时从A地向B地执行送餐任务,收餐者手机尾号为4404。送餐机器人在前方56厘米处有障碍物,底盘正在工作,机械臂与升降平台处于待机状态。送餐机器人整体工作正常,无异常情况出现(如下图所示)。

显示屏工作数据记录

3. 难点及解决方案

3.1转向不流畅且稳定性差

      原有机器人在循迹时因固定差速转弯时,难以适应不同转弯半径,常常因转弯半径过大导致左侧灰度传感器读取右侧灰度传感器或者右侧灰度传感器读取左侧灰度传感器,容易因为传感器数据冲突导致整体不断抖动。

      解决方案:在初步的代码基础上,利用蓝牙外加不断进行速度差调试,同时将实时速度差利用显示屏显示出来,找出最适宜的转向速度,在程序内部进行优化。并将车轮间距进行缩小,减小机器人转弯半径;在此基础之上,加入PID算法,使得速度差根据不同转弯半径不断自行调整差速。

3.2循迹时容易撞上前方或侧方障碍物

      解决方案:利用舵机搭载超声波模块,实现送餐机器人前方210度范围障碍物探测,同时每隔三秒将信号返回值(前方障碍物距离)显示在显示屏上,同时侧方和前方搭载红外避障模块,与超声波共同构成完善的避障系统。在避障程序的编译中,设置了两种代码,根据各模块运动情况实施精准避障,连续避障,合理在小车行进中添加各种采集点、定位点,实现各种不同程度的行走及障碍躲避。

      在机器人四周也加上了红外测距模块,将这些传感器与车身其他专用模块相结合,辅助机器小车在拾取点位更精准,寻迹运动更精确,对四周障碍物做出灵敏的避障。

3.3机械臂稳定性差

      原有机器人的四轴机械臂工作时因延展太长,工作时稳定性较差,容易抖动。

      解决方案:调整机械臂的结构,将原有机械臂两段式结构缩短至一段;并将驱动机械臂工作的四个舵机的偏移量设置为3,大大提高机械臂的稳定性。

3.4循迹稳定性较差

      由于对机器人的初期调试全部在室内完成,使得送餐机器人在室外工作时因光线因素造成灰度传感器的返回值产生误差。

      解决方案:通过多次对室内外机器人循迹时灰度传感器的返回值进行串口读取并记录,不断调整灰度传感的高度的间距,使其因光线差造成的返回值误差降到最低。

3.5机器人工作时重心靠前

      初期建模与组装时未考虑到机械臂工作时伸展及重量问题,导致机械臂工作时,机器人整体重心过于靠前,容易侧翻。

      解决方案:通过solidwork进行运动算例分析,调整机械臂的位置与高度并将车身适当加长(如下图所示)。

修改前后对比

4. 未来前景展望及应用

      与校园或外卖等进行合作试点,不断优化调整,尽快投入市场;改善应用方面,不再局限于送餐,增加功能通过搭载多频段红外传感器、热成像传感器、GPS定位系统等传感器,将校园及周边环境信息导入机器人信息库,辅以语音识别和检索系统,送餐机器人将在校园送餐方面为消费者提供更加个性化、智能化的服务。

送餐机器人整体图

 二、本体设计

 1. 机械结构

      首先利用solidwork建模软件开展机器人结构设计和建模,然后根据建模图样进行组装;在机构设计过程中为了保证机械结构设计合理,使其拥有更加强大的承载力、拥有更大的内部空间,本小组事先对重要机械零件(步进电机底座)进行了应力分析(如下图所示),通过不断对模型的改进和优化设计,最后得到了承载能力强且结构合理的模型。

零件应力分析

送餐机器人整体构造图

1.1底盘

      采用舵机转向、电机驱动的四轮组合结构。利用各种板块零件组合成三角稳定结构制作底盘。这种组合底盘具有稳固和灵敏两个特点:一是对路况的适应能力强,在各种复杂的路况下都可进行基本运动;二是底盘结构稳固灵敏,不限制舵机操控四轮转向位置,也为其它机械结构运转提供了充足空间。底盘及所用电机如下图所示:

送餐机器人底盘和电机

1.2机械臂

      机械臂抓取装置为四轴机械臂,抓取更加灵活,同时在机械爪端部搭配热塑性弹性橡胶,增大机械抓端部抓取餐盒时的摩擦力。

结构如下图所示:

送餐机器人机械臂装置

1.3升降平台

      用于放置餐盒(或餐包)的平台(如下图所示),利用步进电机控制其沿丝杆导轨的升降动作,机械臂将食物放置在平台上后将食物降落到保温装置内,当到达目的地后将食物从保温装置内升起,让机械臂抓取,对其要求是位置精准。

      保温装置布置在升降平台的四周,由聚氨酯泡沫包裹而成,其质量轻、可加工性好、致密度高、保温隔热效果的特点,对放入其中的食物起到保温功能。

送餐机器人升降平台与保温装置

1.4传感器与其它

      送餐机器人除车身主体与底盘外,还搭载超声波模块、红外避障模块、蓝牙模块、人体红外探测模块等多种传感器与模块,各模块与车身之间有防护板材,并进行多重加固,增强了车身的稳定性。

2. 电路控制与设备调试

2.1循迹避障

      循迹避障功能需要用超声波模块、灰度传感器、近红外传感器三者共同作用实现。

如下图所示:

超声波测距模块
红外避障模块
灰度模块

      在舵机的驱动下,超声波模块实现对车头前210度范围进行实时探测,将前方障碍物距离传给单片机,再通过内部蚁群规划算法,规划出合理的避障路线。

      当灰度传感器未识别黑线返回值为0,识别黑线后返回值为1,将返回值传回机器人内部程序,并进行判断。送餐机器人搭载四个灰度传感器,当返回值为0000,机器人前进;只要有一个传感器返回值为1时,通过PID算法对直流电机转速进行调整,控制机器左右转进而实现循迹功能。

      车头与车身两侧搭载了近红外传感器,当监测到机器附近有人通过或存在障碍物,则返回值为0,控制送餐机器人停车。

      红外探测模块探测范围为10cm,超声波模块探测距离为3m-7m。

2.2警示装置

      警示装置由蜂鸣器、车灯、显示屏三部分构成。

      送餐机器人正常工作时,显示屏显示“正常工作”字样,车头指示灯显示绿色;当超声波传感器测到障碍物距离值<50cm时,显示屏显示“行人请注意”字样,同时蜂鸣器间隔性发出“滴滴”声,车前指示灯进行闪烁,提醒路人进行避让;若距离值<16cm时,车灯加快闪烁,蜂鸣器持续发出“滴滴”声,最大程度提醒行人注意避让;当送餐机器人左右转向时,对应方向指示灯也会闪烁;运行停止时,车灯均变为红色;机械臂与升降平台旁分别接一个工作指示灯,配合显示屏使用,工作状态下显示为绿色,待机状态下为红色。

      所用蜂鸣器和指示灯如下图所示:

蜂鸣器模块
工作指示灯

2.3机械臂的运动控制

      机械臂的运动包括旋转、上下移动、机械爪的张合。

      为了实现机械臂的精准夹取与放置,使用了五个舵机控制。底部舵机控制机械臂的左右旋转,中间三个舵机控制机械臂上下移动,末端舵机控制机械爪的张合(如下图所示)。在程序中设定偏移量为3度,即舵机每次以3度转动,减少了机械臂因为惯性所产生的误差,保证了机械臂的平稳运行,使精确性大大提高。

机械臂舵机位置与运动方向

2.4升降平台的控制

      步进电机通过动力传输零件驱动丝杠旋转,丝杠带动平台上的螺母移动,移动过程中通过平台上的卡扣限制平台只能沿上下移动,进而实现平台的升降功能。

      卡扣装置与平台结构如下图所示:

升降平台卡扣装置
升降平台装置

2.5人体红外感应

      送餐机器人到达指定地点后,通过人体红外检测模块,检测人体后返回值为1,升降平台开始运行。将送餐机器人携带的人体红外感应模块设置为可重复模式,并且探测范围设定为3米内,只要在探测范围内取餐者在活动,其信号返回值始终为1。

人体红外探测传感器

2.6蓝牙无线通讯

      基于蓝牙HC-05模块以及NRF905无线收发模块(如下图所示)实现送餐机器人的远距离通讯与控制。当遇到通过的障碍时,通过终端对机器人输入指令,控制机器人运行。

HC-05 蓝牙模块与NRF905模块

三、程序代码

1. 示例程序

① 显示屏代码:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C mylcd(0x27,16,2);byte d[]={0B00000,0B00000,0B11011,0B11011,0B00000,0B11011,0B11011,0B00000};
byte a[]={0B00000,0B00100,0B01000,0B11111,0B11111,0B01000,0B00100,0B00000};
byte b[]={0B00000,0B00000,0B00000,0B11111,0B11111,0B00000,0B00000,0B00000};
byte c[]={0B00000,0B00100,0B00010,0B11111,0B11111,0B00010,0B00100,0B00000};
byte g[]={0B00000,0B11111,0B00100,0B00100,0B00100,0B00100,0B11111,0B00000};
byte h[]={0B00000,0B01010,0B10111,0B01010,0B01011,0B01010,0B01011,0B01010};
byte e[]={0B00000,0B11111,0B00010,0B01011,0B01010,0B01010,0B11111,0B00000};
byte f[]={0B00100,0B01110,0B11111,0B01110,0B01110,0B11111,0B10101,0B00100};void setup(){mylcd.init();mylcd.backlight();mylcd.createchar(1, d);mylcd.createchar(2, a);mylcd.createchar(3, b);mylcd.createchar(4, c);mylcd.createchar(5, g);mylcd.createchar(6, h);mylcd.createchar(7, e);mylcd.createchar(0, f);
}void loop(){mylcd.setCursor(1-1, 1-1);mylcd.print("1");mylcd.setCursor(2-1, 1-1);mylcd.print("2");mylcd.setCursor(3-1, 1-1);mylcd.write(1);mylcd.setCursor(4-1, 1-1);mylcd.print("3");mylcd.setCursor(5-1, 1-1);mylcd.print("8");mylcd.setCursor(7-1, 1-1);mylcd.print("A");mylcd.setCursor(8-1, 1-1);mylcd.write(2);mylcd.setCursor(9-1, 1-1);mylcd.write(3);mylcd.setCursor(10-1, 1-1);mylcd.write(4);mylcd.setCursor(11-1, 1-1);mylcd.print("B");mylcd.setCursor(13-1, 1-1);mylcd.print("4");mylcd.setCursor(14-1, 1-1);mylcd.print("4");mylcd.setCursor(15-1, 1-1);mylcd.print("0");mylcd.setCursor(16-1, 1-1);mylcd.print("4");mylcd.setCursor(1-1, 2-1);mylcd.print("5");mylcd.setCursor(2-1, 2-1);mylcd.print("6");mylcd.setCursor(3-1, 2-1);mylcd.print("c");mylcd.setCursor(4-1, 2-1);mylcd.print("m");mylcd.setCursor(6-1, 2-1);mylcd.write(5);mylcd.setCursor(7-1, 2-1);mylcd.write(6);mylcd.setCursor(8-1, 2-1);mylcd.write(7);mylcd.setCursor(9-1, 2-1);mylcd.write(0);mylcd.setCursor(11-1, 2-1);mylcd.print("1");mylcd.setCursor(12-1, 2-1);mylcd.print("√");mylcd.setCursor(13-1, 2-1);mylcd.print("2");mylcd.setCursor(14-1, 2-1);mylcd.print("#");mylcd.setCursor(15-1, 2-1);mylcd.print("3");mylcd.setCursor(16-1, 2-1);mylcd.print("x");
}

② 底座代码:

#include<SoftwareSerial.h>
SoftwareSerial LZC(A5,A4);
int a=80;
int b=220;
int c=250;
int d=220;
int e=250;
void chaoshengbo();
int i=0;
void setup() {Serial.begin(9600);pinMode(7, INPUT);pinMode(8, INPUT);pinMode(3, INPUT);pinMode(4, INPUT);pinMode(A5, OUTPUT);pinMode(A4, OUTPUT);//右灯pinMode(2, OUTPUT);pinMode(A3, OUTPUT);//左灯
}
void loop() {xunji();  
}
//封装小车前进动作子程序
void Forward() {analogWrite(5, 0);analogWrite(6, a);   //5   6左前     6前       analogWrite(9, 0);  analogWrite(10, a);//9   10右前 v    10前green();
}
//封装小车后退动作子程序
void Backward() {analogWrite(5, a);   //analogWrite(6, 0);analogWrite(9, a);   //analogWrite(10, 0);green();
}//封装小车停止动作子程序
void Stop() {analogWrite(5, 0);   //右轮后退analogWrite(6, 0);analogWrite(9, 0);   //左轮后退analogWrite(10, 0);red();
}//封装小车自转动作子程序
void turn_Left() {analogWrite(5, d);  analogWrite(6, 0);analogWrite(9, 0);  analogWrite(10, b);green();
}//封装小车自转动作子程序
void turn_Right() {analogWrite(5, 0);  analogWrite(6, b);analogWrite(9, d);  analogWrite(10, 0);green();
}//封装小车大半径右转子程序
void turn_Right_1() {analogWrite(5, 0);  analogWrite(6, c);analogWrite(9, e);  analogWrite(10, 0);green();
}//封装小车大半径左转子程序
void turn_Left_1() {analogWrite(5, e);  analogWrite(6, 0);analogWrite(9, 0);  analogWrite(10, c);green();
}void xunji() {int num1, num2, num3, num4;num1 = digitalRead(11);num2 = digitalRead(8);num3 = digitalRead(3);num4 = digitalRead(4);delay(5);//1111   0000    1011   1101     if (num1 == 1 && num2 == 1 && num3 == 1 && num4 == 1) {   //1111Forward();delay(5);}else if (num1 == 1 && num2 == 0 && num3 == 1 && num4 == 1 ) {turn_Left();delay(5);}else if (num1 == 1 && num2 == 1 && num3 == 0 && num4 == 1 ) {turn_Right();delay(5);}else if (num1 == 0 && num2 == 1 && num3 == 1 && num4 == 1 ) {turn_Left_1();delay(5);}else if (num1 == 1 && num2 == 1 && num3 == 1 && num4 == 0 ) {turn_Right_1();delay(5);}else if (num1 == 0 && num2 == 0 && num3 == 1 && num4 == 1 ) {turn_Left_1();delay(30);}else if (num1 == 1 && num2 == 1 && num3 == 0 && num4 == 0 ) {turn_Right_1();delay(5);}else if (num1 == 0 && num2 == 0 && num3 == 0 && num4 == 0) {    //0000Stop();}}
void red()
{digitalWrite( A5 , HIGH );digitalWrite( A4, LOW );digitalWrite( A3, LOW );digitalWrite( 2 , HIGH );
}
void green()
{digitalWrite( A5 , LOW );digitalWrite( A4 , HIGH );digitalWrite( A3 , LOW );digitalWrite( 2 , HIGH );
}

③ 机械臂代码:

#include<SoftwareSerial.h>
SoftwareSerial LZC(A5,A4);
#include <Servo.h>
#include <AccelStepper.h>  // 定义电机控制用常量
const int enablePin = 8;   // 使能控制引脚
const int zdirPin = 5;     // z方向控制引脚
const int zstepPin = 2;    // z步进控制引脚
int trigPin = A0;    //Trig
int echoPin = A1;    //Echo
long duration, cm=0, inches;
const int STEPS_PER_REV = 2800;
AccelStepper stepper3(1,zstepPin,zdirPin);//建立步进电机对象
char X;volatile int sj=25;
volatile int jdu=0;
Servo servo_11;
Servo servo_8;
Servo servo_3;
Servo servo_4;
Servo servo_7;
Servo servo_12;
void setup() {LZC.begin(9600);pinMode(zstepPin,OUTPUT);     // Arduino控制A4988z步进引脚为输出模式pinMode(zdirPin,OUTPUT);      // Arduino控制A4988z方向引脚为输出模式pinMode(enablePin,OUTPUT);   // Arduino控制A4988使能引脚为输出模式digitalWrite(enablePin,LOW); // 将使能控制引脚设置为低电平从而让pinMode(A3, OUTPUT);pinMode(2, OUTPUT);                       // 电机驱动板进入工作状态stepper3.setMaxSpeed(300.0);     // 设置电机最大速度300stepper3.setAcceleration(20.0);   // 设置电机加速度20.0servo_11.attach(11);servo_8.attach(8);servo_3.attach(3);servo_4.attach(4);servo_7.attach(7);servo_12.attach(12);LZC.begin(9600);servo_7.write(45);servo_11.write(135);delay(sj);delay(sj);digitalWrite(2,HIGH);digitalWrite(A3,LOW);for (int i = 150; i >= 105; i = i + (-1)) {servo_4.write(i);delay(sj);servo_3.write(i-10);delay(sj);servo_8.write(305-i);delay(sj);}for (int i = 105; i >= 70; i = i + (-1)) {servo_3.write(i-10);delay(sj);servo_8.write(325-i);delay(sj);}
}void loop() {if( Serial.available())
{X= Serial.read();LZC.print(X);   
}
if(LZC.available())
{X=LZC.read();   Serial.print(X);}switch(X){case 'a':digitalWrite(2,1);digitalWrite(A3,0);LZC.println("开始抓东西");servo_11.write(135);delay(sj);servo_8.write(135);delay(sj);servo_3.write(135);delay(sj);servo_4.write(135);delay(sj);servo_7.write(45);delay(sj);delay(1000);for (int i = 45; i <= 110; i = i + (1)) {servo_7.write(i);delay(sj);}for (int i = 135; i >= 110; i = i + (-1)) {servo_4.write(i);delay(sj);jdu = i;servo_3.write(jdu/2);delay(sj);}for (int i = 110; i <= 150; i = i + (1)) {servo_4.write(i);delay(sj);servo_8.write(255-i);delay(sj);}for (int i = 150; i <= 190; i = i + (1)) {servo_4.write(i);delay(sj);servo_3.write(i-100);delay(sj);}servo_11.write(190);delay(sj);delay(1000);for (int i = 190; i >= 150; i = i + (-1)) {servo_4.write(i);delay(sj);jdu = i;servo_3.write(i-20);delay(sj);servo_8.write(310-i);delay(sj);}for (int i = 150; i >= 125; i = i + (-1)) {servo_4.write(i);delay(sj);servo_3.write(i);delay(sj);servo_8.write(345-i);delay(sj);}for (int i = 110; i <= 170; i = i + (1)) {servo_7.write(i);delay(sj);}servo_11.write(135);delay(sj);delay(1000);for (int i = 170; i >= 42; i = i + (-1)) {servo_7.write(i);delay(sj);}for (int i = 150; i >= 105; i = i + (-1)) {servo_4.write(i);delay(sj);servo_3.write(i-10);delay(sj);servo_8.write(305-i);delay(sj);}delay(10000);break;case 'b':digitalWrite(2,HIGH);digitalWrite(A3,LOW);LZC.println("开始放东西");servo_11.write(135);delay(sj);servo_8.write(135);delay(sj);servo_3.write(135);delay(sj);servo_4.write(135);delay(sj);servo_7.write(45);delay(sj);for (int i = 45; i <= 170; i = i + (1)) {servo_7.write(i);delay(sj);}for (int i = 135; i >= 105; i = i + (-1)) {servo_4.write(i);delay(sj);servo_8.write(i+45);delay(sj);servo_3.write(i-10);delay(sj);}for (int i = 135; i <= 260; i = i + (1)) {servo_8.write(i);delay(sj);}servo_11.write(190);delay(sj);for (int i = 260; i >= 155; i = i + (-1)) {servo_8.write(i);delay(sj);}for (int i = 170; i >= 110; i = i + (-1)) {servo_7.write(i);delay(sj);}for (int i = 90; i <= 150; i = i + (1)) {servo_4.write(i);delay(sj);servo_8.write(i+10);delay(sj);servo_3.write(i-40);delay(sj);}delay(1000);servo_11.write(135);delay(sj);delay(1000);for (int i = 110; i >= 45; i = i + (-1)) {servo_7.write(i);delay(sj);}for (int i = 150; i >= 105; i = i + (-1)) {servo_4.write(i);delay(sj);servo_3.write(i-10);delay(sj);servo_3.write(i-10);delay(sj);servo_8.write(305-i);delay(sj);}for (int i = 105; i >= 70; i = i + (-1)) {servo_3.write(i-10);delay(sj);servo_8.write(325-i);delay(sj);}delay(10000);break;       case 'c':{digitalWrite(2,0);digitalWrite(A3,1);LZC.println("步进电机开始运动");digitalWrite(zdirPin,LOW);// 电机慢速旋转for(int x = 0; x < STEPS_PER_REV; x++) {digitalWrite(zstepPin,HIGH);delayMicroseconds(2000);digitalWrite(zstepPin,LOW);delayMicroseconds(2000);}// 等待一秒delay(10000);break;}case 'd':{   digitalWrite(2,0);digitalWrite(A3,1);LZC.println("步进电机开始运动");// 设置电机逆时针旋转digitalWrite(zdirPin,HIGH);// 电机快速旋转for(int x = 0; x < (STEPS_PER_REV * 2); x++) {digitalWrite(zstepPin,HIGH);delayMicroseconds(1000);digitalWrite(zstepPin,LOW);delayMicroseconds(1000);}// 等待一秒delay(10000);break;
}
case 'e':
{digitalWrite(2,0);digitalWrite(A3,1);LZC.println("云台开始运动");for (int i = 0; i <= 90; i = i + (1)) {servo_12.write(i);delay(15);}for (int i = 90; i >= 0; i = i + (-1)) {servo_12.write(i);delay(15);}break;}
case 'f':
{digitalWrite(2,0);digitalWrite(A3,1);for (int i = 150; i >= 105; i = i + (-1)) {servo_4.write(i);delay(sj);servo_3.write(i-10);delay(sj);servo_8.write(305-i);delay(sj);}for (int i = 105; i >= 70; i = i + (-1)) {servo_3.write(i-10);delay(sj);servo_8.write(325-i);delay(sj);}delay(15000);} }}

2. 资料下载

资料内容:

①程序源代码

②模型3D文件

③仿真渲染文件

④关键零件应力分析图

资料下载地址:送餐机器人

相关文章:

机器人制作开源方案 | 送餐机器人

作者&#xff1a;赖志彩、曹柳洲、王恩开、李雪儿、杨玉凯 单位&#xff1a;华北科技学院 指导老师&#xff1a;张伟杰、罗建国 一、作品简介 1. 场景调研 1.1项目目的 近年来&#xff0c;全国多地疫情频发&#xff0c;且其传染性极高&#xff0c;食品接触是传播途径之一。…...

Gradio部署应用到服务器不能正常访问

用Gradio部署一个基于ChatGLM-6B的应用&#xff0c;发布到团队的服务器上&#xff08;局域网&#xff0c;公网不能访问&#xff09;&#xff0c;我将gradio应用发布到服务器的9001端口 import gradio as gr with gr.Blocks() as demo:......demo.queue().launch(server_port90…...

数据暴涨时代,该如何数据治理?_光点科技

随着信息技术的迅猛发展&#xff0c;数据已经成为现代社会的核心资源。在这个被称为"数据暴涨时代"的时代里&#xff0c;大量的数据源源不断地被产生和积累&#xff0c;但如何有效地管理、分析和利用这些数据成为了一个迫切需要解决的问题。数据治理&#xff0c;作为…...

2021年03月 C/C++(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题&#xff1a;找和为K的两个元素 在一个长度为n(n < 1000)的整数序列中&#xff0c;判断是否存在某两个元素之和为k。 时间限制&#xff1a;1000 内存限制&#xff1a;65536 输入 第一行输入序列的长度n和k&#xff0c;用空格分开。 第二行输入序列中的n个整数&#xff…...

GPT-5出世?OpenAI GPT-5商标已注册

OpenAI的GPT已经成为了业界标杆&#xff0c;升级速度之快让人瞠目&#xff0c;别人追GPT-3.5的时候GPT-4横空出世&#xff0c;差距被拉开了&#xff0c;现在GPT-5就要来了。 据商标律师泄露的消息&#xff0c;OpenAI已于7月18日注册了GPT-5商标。虽然注册商标并不罕见&#xf…...

优雅的使用 Dockerfile 定制镜像

一、使用 Dockerfile 定制镜像 1.1、Dockerfile 定制镜像 镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本&#xff0c;用这个脚本来构建、定制镜像&#xff0c;无法重复的问题、镜像构建透明性的问题、…...

limit的用法mysql

当你在 MySQL 数据库中使用 LIMIT 语句&#xff0c;它可以用于限制查询结果的行数。这在分页查询或者限制返回的数据量时非常有用。下面是一些示例&#xff1a; 返回前几行数据&#xff1a; SELECT * FROM Customers LIMIT 5;这将返回 Customers 表中的前 5 行数据。 分页查…...

clickhouse Checksum doesn‘t match: 问题修复

1. 问题描述 SQL 错误 [40] [07000]: Code: 40. DB::Exception: Checksum doesnt match: corrupted data. Reference: 50e8c1efa78de2881b725d44b04be1fe. Actual: 161c99eb681ec36b83540ecdd65ad8c9. Size of compressed block: 32846. The mismatch is caused by single bit…...

企业如何开展个人信息安全影响评估(PIA)二

基本概念 根据《信息安全 技术个人信息安全影响评估指南》&#xff08;GB/T 39335—2020&#xff1b;personal information security impact assessment&#xff0c;简称“PIA”&#xff09;&#xff0c;个人信息安全影响评估是指针对个人信息处理活动&#xff0c;检验其合法合…...

android TextView 超出长度使用省略号

在Android中最常见的需求&#xff0c;就是在在外部展示信息时&#xff0c;需要简要展示内容。TextView仅需在静态布局文件中设置以下几个属性&#xff1a; android:maxWidth“100dp” // 宽度是多少才算超出 android:maxLines"2" // 高度多少才算超出 android:elli…...

c++ | 字节转换 | 字长 | 机器位数

为什么有的时候脑子转不过来&#xff1f;&#xff1f; 为什么要对字节、机器长啊、位啊都要门清 位数 一般的就是指计算机的位数&#xff0c;比如64位/32位&#xff0c;更简单的理解&#xff0c;计算机就是在不停的做二进制的计算&#xff0c;比如32位计算机&#xff0c;在长…...

7-4 交换最小值和最大值

分数 15 全屏浏览题目 切换布局 作者 C课程组 单位 浙江大学 本题要求编写程序&#xff0c;先将输入的一系列整数中的最小值与第一个数交换&#xff0c;然后将最大值与最后一个数交换&#xff0c;最后输出交换后的序列。 注意&#xff1a;题目保证最大和最小值都是唯一的。…...

解决Pycharm的Settings中Project不见了也无法选择Python Interpreter的方法

目录 一、问题如下二、解决方法 一、问题如下 突然打开项目没有python解释器&#xff0c;也无法重新配置python Interpreter&#xff0c;而且整个文件夹是黄色高亮的形式&#xff0c;如下显示&#xff0c;而且重新安装了pycharm也没用甚至说打开File–>Setting–>Projec…...

AWS EKS 集群自动扩容 Cluster Autoscaler

文章目录 一&#xff0c;需求工作需求说明 二&#xff0c;部署精简命令执行1&#xff0c;要求2&#xff0c;查看EC2 Auto Scaling groups Tag3&#xff0c;创建Serviceaccount需要的Policy&#xff0c;Role4&#xff0c;部署Cluster Autoscaler5&#xff0c;验证6&#xff0c;常…...

excel中有哪些通配符、excel配置问题,数学函数篇1之sum系列

学习excel前需要明确的是事&#xff1a;   在学习excel函数之前&#xff0c;大家需要明确一件事&#xff0c;excel现在设计到了一些新函数&#xff0c;这些新函数只能存在于office365、office2019及更 新版本之中&#xff0c;所以建议大家在学习时安装较新的版本&#xff0c;…...

工控行业需要熟悉的工业级通信协议

1. Modbus RTU Modbus RTU 是一种串行通信协议&#xff0c;常用于工控行业。它具有以下特点和优势&#xff1a; 采用二进制编码&#xff0c;数据传输更加高效。支持多种传输介质&#xff0c;如RS-232、RS-485等。容易实现和使用&#xff0c;适用于各种设备。具备强大的错误检…...

力扣题解(1030. 距离顺序排列矩阵单元格),带注释

题目描述 链接:点我 注意&#xff1a;多看几遍题目&#xff0c;开始没看懂…相当于计算矩阵网格里面的点&#xff08;不要计算边界&#xff09; 我开了题解才明白题的意思 orz… 题解 class Solution {public int[][] allCellsDistOrder(int rows, int cols, int rCenter, …...

每天一道leetcode:剑指 Offer 34. 二叉树中和为某一值的路径(中等图论深度优先遍历递归)

今日份题目&#xff1a; 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例1 输入&#xff1a;root [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSu…...

利用POM完成脚本分离实现企业级自动化(POM设计模式+页面的框架封装+测试报告截图)

利用POM完成脚本分离实现企业级自动化&#xff08;POM设计模式页面的框架封装测试报告截图&#xff09; 项目-测试-手工测试 项目-测试-手工测试 1.了解需求&#xff1b; 2.编写测试用例&#xff08;开始&#xff09;——功能测试组会去做的事情 3.执行测试用例——发送测试报…...

嵌入式设计中对于只有两种状态的变量存储设计,如何高效的对循迹小车进行偏差量化

前言 &#xff08;1&#xff09;在嵌入式程序设计中&#xff0c;我们常常会要对各类传感器进行数据存储。大多时候的传感器&#xff0c;例如红外光传感器&#xff0c;返回的数据要么是0&#xff0c;要么是1。因此&#xff0c;只需要一bit就能够存储。而很多人却常常使用char型数…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...

深入浅出WebGL:在浏览器中解锁3D世界的魔法钥匙

WebGL&#xff1a;在浏览器中解锁3D世界的魔法钥匙 引言&#xff1a;网页的边界正在消失 在数字化浪潮的推动下&#xff0c;网页早已不再是静态信息的展示窗口。如今&#xff0c;我们可以在浏览器中体验逼真的3D游戏、交互式数据可视化、虚拟实验室&#xff0c;甚至沉浸式的V…...