亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

全向轮跟随机器人:OpenCV 人脸检测与安全陪伴

零部件与物料

零部件 数量 备注
L298N 双电机驱动板 2 驱动 3 个麦克纳姆轮电机
LM2596 降压模块 1 12V→5V 供电 Ci20 与 Arduino
锂电池低压报警器 1 防止过放保护电池
24RPM 12V 减速电机 (4mm 轴) 3 三全向轮驱动
Arduino Nano R3 1 电机底层控制
Microsoft LifeCam HD-3000 摄像头 1 USB 接入 Ci20,人脸检测
Creator Ci20 开发板 1 双核 MIPS,运行 OpenCV
11.1V 3S 锂聚合物电池 1 主电源
跳线若干 1 套 电源与信号连接

所需工具

软件与在线服务

项目简介

这是一个「反向终结者」机器人:不伤害人类,而是主动寻找人脸、靠近并赞美你!项目名为 Hunter Flatterer Robot,采用三轮全向驱动(麦克纳姆轮),可平移、旋转、斜向移动,配合 Ci20 开发板运行 OpenCV 人脸检测,通过串口指挥 Arduino Nano 控制三电机矢量合成,实现平滑跟随。

全向轮跟随机器人:OpenCV 人脸检测与安全陪伴
系统框图:电池→降压→Ci20/Arduino;Ci20 USB 摄像头→OpenCV→串口→Arduino→3×L298N→3 电机

四大子系统

  1. 电源管理:11.1V 3S LiPo → LM2596 降压 5V 供 Ci20、Arduino、逻辑电路;电机直供 12V;低压报警器监控电池
  2. Ci20 视觉大脑:运行 Linux,OpenCV 加载 Haar 级联分类器 (haarcascade_frontalface_default.xml) 实时检测人脸,计算人脸中心偏移量,发送 X Y 或旋转指令 R ms 给 Arduino
  3. Arduino 运动控制:接收串口指令,将 (X,Y) 映射为三电机速度矢量 (w1,w2,w3),通过 L298N PWM 驱动
  4. 3D 打印机械结构:底盘容纳电池、Ci20、Arduino;盖板展示 Ci20;三麦克纳姆轮直接连接电机轴

Ci20 OpenCV 部署

  1. 安装 OpenCV:参考官方教程编译安装 opencv4 至 /usr/local
  2. 编译人脸跟踪程序:
    g++ -I/usr/local/include/opencv -I/usr/local/include/opencv2 \
        -L/usr/local/lib/ -g -o FaceTracker main.cpp \
        -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_ml \
        -lopencv_video -lopencv_features2d -lopencv_calib3d \
        -lopencv_objdetect -lopencv_contrib -lopencv_legacy -lopencv_stitching
    
  3. 运行 ./FaceTracker,弹出摄像头窗口,人脸居中时发送 F 50 50 前进,偏左/偏右发送相应矢量,无人脸发送 0 0 停止

Arduino 运动学解算

三轮全向模型(120° 间隔):

// 目标速度矢量 (vx, vy)
float theta = atan2(y, x);
float mag = sqrt(x*x + y*y);
float vx = mag * cos(theta);
float vy = mag * sin(theta);

// 三电机速度分解
float w1 = -vx;
float w2 = 0.5*vx - sqrt(3)/2*vy;
float w3 = 0.5*vx + sqrt(3)/2*vy;

// 归一化到 PWM 0-255
float maxW = max(abs(w1), max(abs(w2), abs(w3)));
float scale = 147.0 / maxW;  // 经验系数
w1 *= scale; w2 *= scale; w3 *= scale;
w1 = constrain(w1, -150, 150); // 同 w2, w3
// 方向位 + PWM 速度输出到 L298N

3D 打印件

全向轮跟随机器人:OpenCV 人脸检测与安全陪伴
成品渲染图

未完成的挑战(留给读者)

代码

Arduino 主程序 (接收串口指令、驱动电机)

// Motor 1
int dir1PinA = 3, dir2PinA = 2, speedPinA = 9;
// Motor 2
int dir1PinB = 4, dir2PinB = 5, speedPinB = 8;
// Motor 3
int dir1PinC = 6, dir2PinC = 7, speedPinC = 10;

String rpiString;
int x = 0, y = 0;
unsigned long lastCmd = 0;

void setup() {
  Serial.begin(9600);
  // 所有引脚设为 OUTPUT
  for (int p : {dir1PinA,dir2PinA,speedPinA,dir1PinB,dir2PinB,speedPinB,dir1PinC,dir2PinC,speedPinC})
    pinMode(p, OUTPUT);
  lastCmd = millis();
}

void loop() {
  readSerial();
  // 超时保护:1 秒无指令自动停车
  if (millis() - lastCmd > 1000) { x = 0; y = 0; }
  if (x != 0 || y != 0) driveInDirection(x, y);
  else stopAll();
  delay(30);
}

void readSerial() {
  while (Serial.available()) {
    char c = Serial.read();
    if (c == 'n') break; // 指令以 'n' 结尾
    rpiString += c;
  }
  if (rpiString.length() > 0) {
    String cmd = getValue(rpiString, ' ', 0);
    x = getValue(rpiString, ' ', 1).toInt();
    y = getValue(rpiString, ' ', 2).toInt();
    lastCmd = millis();
    if (cmd == "r") rotate(x); else driveInDirection(x, y);
    rpiString = "";
  }
}

String getValue(String data, char sep, int index) {
  int found = 0, strIndex[] = {0, -1};
  for (int i = 0; i <= data.length()-1 && found <= index; i++) {
    if (data.charAt(i) == sep || i == data.length()-1) {
      found++;
      strIndex[0] = strIndex[1] + 1;
      strIndex[1] = (i == data.length()-1) ? i+1 : i;
    }
  }
  return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}

Arduino 运动控制库 (需放同一文件夹)

void driveInDirection(float x, float y) {
  delay(20);
  float theta = atan2(y, x);
  float mag = sqrt(x*x + y*y);
  float vx = mag * cos(theta), vy = mag * sin(theta);
  float w1 = -vx;
  float w2 = 0.5*vx - sqrt(3)/2*vy;
  float w3 = 0.5*vx + sqrt(3)/2*vy;
  float wSet[3] = {w1, w2, w3};
  float maxW = 0;
  for (int i=0;i<3;i++) if (abs(wSet[i]) > maxW) maxW = abs(wSet[i]);
  float scale = 147.0 / maxW;
  for (int i=0;i<3;i++) wSet[i] *= scale;
  if (x==0 && y==0) { w1=w2=w3=0; }
  // 限幅、映射 PWM、设置方向位、analogWrite...
  // 详见完整代码附件
}

void rotate(float ms) {
  // 三轮同向全速旋转 ms 毫秒
  // 详见完整代码附件
}

Ci20 OpenCV 人脸跟踪 (C++)

#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include 
#include 
#include 
#include 

using namespace std; using namespace cv;

CascadeClassifier face_cascade;
string win_name = "Face Detection";

int sendSerial(const char* msg) {
  int fd = open("/dev/ttyUSB0", O_RDWR);
  if (fd == -1) return 1;
  struct termios t; tcgetattr(fd, &t);
  t.c_iflag = IGNBRK | IGNPAR; t.c_oflag = 0; t.c_lflag = 0;
  cfsetspeed(&t, B9600); tcsetattr(fd, TCSAFLUSH, &t);
  usleep(1000);
  write(fd, msg, strlen(msg));
  close(fd); return 0;
}

void detectFaces(Mat frame) {
  vector faces; Mat gray;
  cvtColor(frame, gray, COLOR_BGR2GRAY);
  equalizeHist(gray, gray);
  face_cascade.detectMultiScale(gray, faces, 1.1, 3, 0|CASCADE_SCALE_IMAGE, Size(30,30));
  for (size_t i=0; i frame.cols/3 && center.x < frame.cols*2/3)
      sendSerial("F 50 50"); // 前进
    else
      sendSerial("0 0");     // 停止/微调
  }
  imshow(win_name, frame);
}

int main() {
  sendSerial("0 0");
  VideoCapture cap(0);
  cap.set(CAP_PROP_FRAME_WIDTH, 480);
  cap.set(CAP_PROP_FRAME_HEIGHT, 240);
  if (!face_cascade.load("haarcascade_frontalface_default.xml")) return -1;
  Mat frame;
  while (cap.read(frame)) {
    detectFaces(frame);
    if (waitKey(30) >= 0) break;
  }
  return 0;
}

自定义零件与外壳

原理图

全向轮跟随机器人:OpenCV 人脸检测与安全陪伴
电源分配与信号连接原理图

制造工艺

  1. 工业机器人:设计逻辑、制造体系与智能化未来
  2. 树莓派 OpenCV 乒乓球追踪进阶教程
  3. Raspoulette:太阳能自主鸡舍门控制系统原型
  4. DIY仿Wall-E树莓派CD盒机器人
  5. 滚动闹钟机器人:树莓派+Google Calendar智能移动唤醒系统
  6. 在 Windows 10 IoT Core 上构建语音驱动的计算机视觉机器人
  7. ROS 机器人:树莓派终端控制导航
  8. Simple Pi Robot:用树莓派打造 2WD 自主巡航车
  9. 适用于 Arduino 项目的智能室内导航机器人套件
  10. 线性电机原理与演进:从电能到精密直线运动的技术演变
  11. 饮料机器人:自动化技术重塑饮品服务新体验
  12. 伺服电机深度解析:工作原理、分类与核心价值