一、任务
设计一基于四旋翼飞行器的巡线机器人,能够巡检电力线路及杆塔状态 (见图 1),发现异常时拍摄存储,任务结束传送到地面显示装置上显示。巡线 机器人中心位置需安装垂直向下的激光笔,巡线期间激光笔始终工作,以标识 航迹。
二、要求
1.基本要求
(1) 巡线机器人从距 A 杆塔 1 米范围内的起飞点起飞,以 1 米定高绕杆巡检,巡检流程为:起飞→杆塔 A→电力线缆→绕杆塔 B→电力线缆→杆塔 A,然后稳定降落;巡检期间,巡线机器人激光笔轨迹应落在地面虚线框内。
(2) 从起飞到降落,巡线完成时间不得大于 150 秒,巡线时间越短越好。
(3) 发现线缆上异物(黄色凸起物),巡线机器人须在与异物距离不超过30cm 的范围内用声或光提示。
2.发挥部分
(1) 拍摄所发现线缆异物上的条形码图片存储到 SD 卡,巡检结束后在显示装置上清晰显示,并能用手机识别此条形码内容。
(2) 发现并拍摄杆塔 B 上的二维码图片存储到 SD 卡,巡检结束后在显示装置上清晰显示,并能用手机识别此二维码内容。
(3) 拍摄每张条形码、二维码图片存储的照片数不得超过 3 张。
(4) 停机状况下,在巡线机器人某一旋翼轴下方悬挂一质量为 100g 的配重,然后巡线机器人在图 3所示环形圆板上自主起飞,并在 1 米高度平稳悬停 10 秒以上,且摆动范围不得大于±25cm。
(5) 在测试现场随机选择一个简单飞行动作任务,30分钟内现场编程调试完成飞行动作。
(6) 其他。
三、说明
1. 电力线缆与杆塔说明
(1) 线缆的直径不大于 5mm,颜色为黑色。
(2) 杆塔高度约 150cm,直径不大于 30mm。
(3) 线缆上异物上粘贴有圆环状的黄底黑色 8 位数条形码,条形码宽度约30±2mm,见图 4。
(4) 线缆上的异物为黄色(红绿蓝三原色参数为:R-255,G-255,B-0),直径约 30±2mm,长度约 50±5mm。
(5) 二维码粘贴在杆塔 B 上与线缆连接处外侧,大小 30±3mm 见方,见图 5。
2.巡线机器人要求:
(1) 参赛队所用飞行器应遵守中国民用航空局的管理规定(《民用无人驾驶航 空器实名制登记管理规定》,编号:AP-45-AA-2017-03)。
(2) 四旋翼飞行器最大轴间距不大于 420mm。
(3) 为确保安全,飞行器桨叶须全防护(防护圈将飞行器或桨叶全包),否则不得测试;测试区应设置防护网。
(4) 巡线机器人不得有“无线通信及遥控”功能。
(5) 除飞行器机械构件、飞行控制(电调)、摄像功能模块外,巡线机器人其他功能的实现不得采用飞行器集成商提供的组件,必须自主设计完成。
(6) 激光笔可采用悬挂等软连接方式。
3. 测试流程说明
(1) 起飞前,飞行器可手动放置到起飞点;可手动控制起飞;起飞后整个巡检过程中不得人为干预。
(2) 从基本部分(1)到发挥部分(3)的巡线工作须一次连续完成,期间不得人为干预,也不得更换电池;允许测试 2 次,按最好成绩记录;两次测试间可更换电池。
(3) 发挥部分(1)、(2)中拍摄的条形码及二维码图片存储在存储介质(如SD 卡)中,巡线完成后在地面显示装置上读取显示,用手机识别;手机及显示装置作为作品的组成部分,必须与作品一起封存。
(4) 在巡线区地面标识±60cm 区域,见图 1,巡线机器人巡检航迹可参照激光笔光点轨迹摄像判定。
(5) 基本部分(1)到发挥部分(3)测试完成后,进行发挥部分(4)测试;增加配重后,不得自行另加其他配重。
(6) 现场编程实现的任务在所有其他测试工作(包括“其他”项目)完成之后进行。编程调试超时判定任务未完成;编程调试时间计入成绩。编程下载工具必须与作品一起封存。
(7) 测试现场应避免窗外强光直接照射,避免高照度点光源照明;尽量采用多点分布式照明,以减小飞行器自身投影的影响。
(8) 飞行场地地面可采用图 6 所示灰白条纹纸质材料铺设。灰白条纹各宽20mm,灰色的红绿蓝三原色参数为:R-178,G-178,B-178。
(9) 飞行期间,飞行器触及地面后自行恢复飞行的,酌情扣分;触地后 5秒内不能自行恢复飞行视为失败,失败前完成动作仍有效。
(10)平稳降落是指在降落过程中无明显的跌落、弹跳及着地后滑行等情况出现。
(11)调试及测试时必须佩带防护眼镜,穿戴防护手套。
东南大学 胡仁杰老师—寻找机器人(B题)交流及2020年模拟邀请赛介绍
上述方案旨在全面满足项目要求的同时,确保系统的稳定性和可靠性。希望这个设计方案能为你的项目提供有价值的参考。
以下是涉及到的几个关键算法的实现思路和代码示例,从飞行控制、图像处理、条码识别到数据通信等。
为了实现无人机的飞行控制,常用的算法是 PID 控制算法。下面是一个简单的 PID 控制算法的 C++ 示例代码。
class PID {
public:
PID(float kp, float ki, float kd) : kp_(kp), ki_(ki), kd_(kd) {}
float compute(float setpoint, float measured_value) {
float error = setpoint - measured_value;
float derivative = (error - previous_error_);
integral_ += error;
float output = kp_ * error + ki_ * integral_ + kd_ * derivative;
previous_error_ = error;
return output;
}
private:
float kp_, ki_, kd_;
float previous_error_ = 0;
float integral_ = 0;
};
// 使用示例
PID altitude_pid(1.0, 0.5, 0.3);
使用 OpenCV 库进行图像处理和条形码识别。以下是在嵌入式系统中使用 OpenCV 进行条形码识别的 C++ 代码示例。
#include <opencv2/opencv.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <zbar.h>
using namespace cv;
using namespace zbar;
// 图片预处理函数
Mat preprocessImage(Mat &src) {
Mat gray, binarized;
cvtColor(src, gray, COLOR_BGR2GRAY);
threshold(gray, binarized, 0, 255, THRESH_BINARY | THRESH_OTSU);
return binarized;
}
// 条形码识别函数
std::string decodeBarcode(Mat &image) {
ImageScanner scanner;
scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);
Mat processed = preprocessImage(image);
int width = processed.cols;
int height = processed.rows;
uchar *raw = (uchar *)(processed.data);
Image zbarImage(width, height, "Y800", raw, width * height);
scanner.scan(zbarImage);
std::string result;
for (Image::SymbolIterator symbol = zbarImage.symbol_begin(); symbol != zbarImage.symbol_end(); ++symbol) {
result = symbol->get_data();
}
return result;
}
// 使用示例
int main() {
Mat image = imread("barcode.jpg");
if (image.empty()) {
std::cerr << "Could not read the image" << std::endl;
return 1;
}
std::string barcodeData = decodeBarcode(image);
std::cout << "Barcode data: " << barcodeData << std::endl;
return 0;
}
实现无人机与地面站的数据通信,可以使用常见的无线通信协议,比如 Wi-Fi 或者 4G 模块。以下是使用 Wi-Fi 模块进行简单 TCP 通信的 C++ 示例代码。
服务端(地面站)代码:
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <cstring>
#define PORT 8080
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
const char *hello = "Hello from server";
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
std::cerr << "Socket failed" << std::endl;
exit(EXIT_FAILURE);
}
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
std::cerr << "setsockopt" << std::endl;
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
std::cerr << "Bind failed" << std::endl;
exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0) {
std::cerr << "Listen" << std::endl;
exit(EXIT_FAILURE);
}
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
std::cerr << "Accept" << std::endl;
exit(EXIT_FAILURE);
}
int valread = read(new_socket, buffer, 1024);
std::cout << buffer << std::endl;
send(new_socket, hello, strlen(hello), 0);
std::cout << "Hello message sent" << std::endl;
close(new_socket);
close(server_fd);
return 0;
}
客户端(无人机)代码:
#include <iostream>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 8080
int main() {
int sock = 0;
struct sockaddr_in serv_addr;
char buffer[1024] = {0};
const char *hello = "Hello from client";
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
std::cerr << "Socket creation error" << std::endl;
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
std::cerr << "Invalid address/ Address not supported" << std::endl;
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
std::cerr << "Connection failed" << std::endl;
return -1;
}
send(sock, hello, strlen(hello), 0);
std::cout << "Hello message sent" << std::endl;
int valread = read(sock, buffer, 1024);
std::cout << buffer << std::endl;
close(sock);
return 0;
}
以上代码及算法实现示例涵盖了无人机飞行控制(PID算法)、图像处理与条形码识别(基于OpenCV库和ZBar库)、以及无人机与地面站的数据通信(基于TCP/IP协议)。这些部分共同协作,才能完成基于四旋翼飞行器的巡线机器人任务。确保代码在具体硬件平台上的适配以及性能调优是后续实现过程中需要特别注意的。