用真实的机器人做人脸跟踪器---37

原创博客:转载请标明出处:http://www.cnblogs.com/zxouxuewei/

 

1,首先对于整体框架要搞明白,我们学东西不是为了看现象,是为了明白原理。如果没有一个全局的软件框架又怎么能做出创新的东西呢?其实这句话是在告诉我自己。

本次尝试也只会在/cmd_val话题中的z方向上有数据,所以机器人只能左右转。

2.其次就是运行你自己的机器人框架,实质上机器人需要订阅/cmd_val话题下的数据。通过串口下发给终端控制器解析后相应的移动机器人。具体实现可以看我前面的博文。

http://www.cnblogs.com/zxouxuewei/p/5352143.html

以下代码是我的机器人平台的tf_broadcaster_node.cpp节点,在此仅做参考:

 
  
 
  
#include <ros/ros.h>
#include <sensor_msgs/JointState.h>
#include <tf/transform_broadcaster.h>
#include <nav_msgs/Odometry.h>
#include <iostream>
#include <iomanip>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <math.h>
#include "string.h"
 
using namespace std;
using namespace boost::asio;
 
double x = 0.0;
double y = 0.0;
double th = 0.0;
double vx = 0.0;
double vy = 0.0;
double vth = 0.0;
double dt = 0.0;


//Defines the packet protocol for communication between upper and lower computers
#pragma pack(1)
typedef union _Upload_speed_   
{
    unsigned char buffer[16];
    struct _Speed_data_
    {
        float Header;
        float X_speed;
        float Y_speed;
        float Z_speed;
    }Upload_Speed;
}Struct_Union;
#pragma pack(4)

//Initializes the protocol packet data
Struct_Union Reciver_data        = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};  
Struct_Union Transmission_data   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};   
 
//Defines the message type to be transmitted geometry_msgs
geometry_msgs::Quaternion odom_quat;
 
void cmd_velCallback(const geometry_msgs::Twist &twist_aux)
{
    geometry_msgs::Twist twist = twist_aux;
    
    Transmission_data.Upload_Speed.Header = header_data;
    Transmission_data.Upload_Speed.X_speed = twist_aux.linear.x;
    Transmission_data.Upload_Speed.Y_speed = twist_aux.linear.y;
    Transmission_data.Upload_Speed.Z_speed = twist_aux.angular.z;
}


int main(int argc, char** argv)
{
    unsigned char check_buf[1];
    std::string usart_port,robot_frame_id,smoother_cmd_vel;
    int baud_data;
    float p,i,d;
    
    ros::init(argc, argv, "base_controller");
    ros::NodeHandle n;
    ros::Time current_time, last_time;
    
    //Gets the parameters in the launch file
    ros::NodeHandle nh_private("~");
    nh_private.param<std::string>("usart_port", usart_port, "/dev/robot_base");
    nh_private.param<int>("baud_data", baud_data, 115200);
    nh_private.param<std::string>("robot_frame_id", robot_frame_id, "base_link");
    nh_private.param<std::string>("smoother_cmd_vel", smoother_cmd_vel, "/cmd_vel");
    
    
    //Create a boot node for the underlying driver layer of the robot base_controller
    ros::Subscriber cmd_vel_sub = n.subscribe(smoother_cmd_vel, 50, cmd_velCallback);
    ros::Publisher odom_pub = n.advertise<nav_msgs::Odometry>("odom", 50);
    tf::TransformBroadcaster odom_broadcaster;
    
    //Initializes the data related to the boost serial port
    io_service iosev;
    serial_port sp(iosev, usart_port);
    sp.set_option(serial_port::baud_rate(baud_data));
    sp.set_option(serial_port::flow_control(serial_port::flow_control::none));
    sp.set_option(serial_port::parity(serial_port::parity::none));
    sp.set_option(serial_port::stop_bits(serial_port::stop_bits::one));
    sp.set_option(serial_port::character_size(8));
    
    while(ros::ok())
    {
        ros::spinOnce();
        //Gets the cycle of two time slice rotations. The purpose is to calculate the odom message data
        current_time = ros::Time::now();
        dt = (current_time - last_time).toSec();
        last_time = ros::Time::now();
              
        //Read the data from the lower computer
        read(sp, buffer(Reciver_data.buffer));
        if(Reciver_data.Upload_Speed.Header > 15.4 && Reciver_data.Upload_Speed.Header < 15.6)
        {
                vx  = Reciver_data.Upload_Speed.X_speed;
                vy  = Reciver_data.Upload_Speed.Y_speed;
                vth = Reciver_data.Upload_Speed.Z_speed;
                //ROS_INFO("%2f    %2f    %2f",vx,vy,vth);
        }
        else
        {  
            //ROS_INFO("------Please wait while the robot is connected!-----");
            read(sp, buffer(check_buf));
        }
        //Send the next bit machine under the cmd_val topic to monitor the speed information
        write(sp, buffer(Transmission_data.buffer,16));
        //Calculate odometer data
        double delta_x = (vx * cos(th) - vy * sin(th)) * dt;
        double delta_y = (vx * sin(th) + vy * cos(th)) * dt;
        double delta_th = vth * dt;
        x += delta_x;
        y += delta_y;
        th += delta_th;
         
        geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromYaw(th);
         
        geometry_msgs::TransformStamped odom_trans;
        odom_trans.header.stamp = current_time;
        odom_trans.header.frame_id = "odom";
        odom_trans.child_frame_id = robot_frame_id;
 
        odom_trans.transform.translation.x = x;
        odom_trans.transform.translation.y = y;
        odom_trans.transform.translation.z = 0.0;
        odom_trans.transform.rotation = odom_quat;
         
        odom_broadcaster.sendTransform(odom_trans);
         
        nav_msgs::Odometry odom;
        odom.header.stamp = current_time;
        odom.header.frame_id = "odom";
         
        odom.pose.pose.position.x = x;
        odom.pose.pose.position.y = y;
        odom.pose.pose.position.z = 0.0;
        odom.pose.pose.orientation = odom_quat;
 
         
        odom.child_frame_id = robot_frame_id;
        odom.twist.twist.linear.x = vx;
        odom.twist.twist.linear.y = vy;
        odom.twist.twist.angular.z = vth;
        //Release odometer data between odom-> base_link
        odom_pub.publish(odom);
    }
    iosev.run();
}



 

我的机器人平台需要运行以下节点:

rosrun odom_tf_package tf_broadcaster_node

3.因为我们采用的RGB图像是来源于kinect,首先确保你的kinect相机驱动能正常启动:(如果你没有安装kinect深度相机驱动,请看我前面的博文。http://www.cnblogs.com/zxouxuewei/p/5271939.html)

roslaunch openni_launch openni.launch

4.运行脸部跟踪器。

roslaunch rbx1_vision face_tracker2.launch

5.运行物体跟踪节点

roslaunch rbx1_apps object_tracker.launch

当然此时你可以查看/cmd_vel话题下的数据。

rostopic echo /cmd_vel

6.以下是我的测试结果:

 显示msg_encoder.angular_z数据的终端是我监听的机器人编码器结算的速度信息,当然你的机器人也在做跟踪的效果。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
欢迎下载研华科技主题白皮书: 【深度剖析】研华多核异构ARM核心板之机器视觉应用案例 [摘要] TI Sitara系列AM5718/5728是采用ARM+DSP多核异构架构,可以实现图像采集、算法处理、显示、控制等功能,具有实时控制、低功耗、多标准工业控制网络互联、工业人机界面的优化、2D/3D图形处理、1080 HD的高清视频应用、工业控制设备的小型化等特点。广泛应用在机器视觉、工业通讯、汽车多媒体、医疗影像、工厂自动化、工业物联网等领域。 https://www.eefocus.com/resource/advantech/index.p... OpenMV Cam概述: OpenMV项目旨在通过开发开源的低成本机器视觉摄像机,为业余爱好者和制造商提供机器视觉。OpenMV项目于2015年成功通过Kickstarter资助。第一代OpenMV摄像机基于STM的STM32F ARM Cortex-M MCU和Omnivision OV7725传感器。OpenMV摄像机可以在Python3中进行编程,并附有大量的图像处理功能,如面部检测和跟踪,关键点描述符,彩色斑点跟踪,QR和条形码支持,AprilTags,GIF和MJPEG记录等等。 OpenMV摄像机板内置RGB和红外LED,用于编程和视频流的USB FS,uSD插座和I / O头,可以分解PWM,UART,SPI和I2C。此外,OpenMV还支持使用诸如WiFi,BLE,Thermal(FIR)和LCD屏蔽等I / O头的扩展模块(屏蔽)。 OpenMV配备了专门用于支持OpenMV摄像机的跨平台IDE(基于QT创建者)。IDE允许查看帧缓冲区,访问传感器控制,上传脚本并通过串行通过USB(或WiFi / BLE(如果可用))在相机上运行它们。 STM32 机器人视觉摄像机OpenMV Cam实物截图: STM32 机器人视觉摄像机OpenMV Cam特性: 所有I / O引脚输出3.3V并具有5V容限。 在标准的M12镜头座上配有一个2.8mm镜头,便于其他镜头交换。 全速USB(12Mbs)接口到您的计算机。您的OpenMV摄像机在插入时将显示为虚拟COM端口和USB闪存驱动器。 一个能够100Mb读/写的微型SD卡插槽,允许您的OpenMV摄像头记录视频并轻松拉取机器视觉资产从微型SD卡。 SPI总线可以运行高达45Mbs,使您可以轻松地将系统中的图像数据传输到LCD屏蔽,WiFi屏蔽或另一个微控制器。 I2C总线,CAN总线和异步串行总线(TX / RX),用于与其他微控制器和传感器接口。 12位ADC和12位DAC。 两个用于伺服控制的I / O引脚。 所有I / O引脚上的中断和PWM(板上有9个I / O引脚)。 另外还有一个RGB LED和两个高功率的850nm红外LED。 由MacroFab在美国制造的OpenMV LLC OpenMV Cam M4 与 M7区别: STM32 机器人视觉摄像机OpenMV Cam应用: 标记跟踪 您可以使用您的OpenMV Cam来检测组的颜色,而不是独立的颜色。这允许您创建可以放置在对象上的色彩制作者(2个或更多颜色标签),允许您的OpenMV Cam了解标签对象的内容。视频演示这里。 人脸检测 您可以使用OpenMV Cam(或任何通用对象)检测Faces。您的OpenMV Cam可以处理Haar Cascades进行通用对象检测,并配有内置的Frontal Face Cascade和Eye Haar Cascade来检测脸部和眼睛。 眼睛追踪 您可以使用眼动跟踪与您的OpenMV摄像头来检测某人的注视。然后,您可以使用它来控制机器人。眼睛跟踪检测瞳孔的位置,同时检测图像中是否有眼睛。 光流 您可以使用光流来检测您的OpenMV摄像机正在查看的翻译。例如,您可以使用四通孔上的光流来确定其在空气中的稳定性。 QR码检测/解码 您可以使用OpenMV Cam在其视野中读取QR码。通过QR码检测/解码,您可以使智能机器人能够读取环境中的标签。您可以在此处查看我们的视频。 边缘/线路检测 您可以通过Canny Edge Detector算法或简单的高通滤波进行边缘检测,然后进行阈值处理。在您拥有二进制图像后,您可以使用霍夫检测器查找图像中的所有行。通过边缘/线检测,您可以使用OpenMV Cam来轻松检测对象的方向。 模板匹配 您可以使用与OpenMV Cam模板匹配来检测翻译的预先保存的图像何时被视图。例如,可以使用模板匹配来查找PCB上的基准或读取显示器上的已知数字。 图像捕获 您可以使用OpenMV摄像头捕获多达320x240 RGB565(或640x480灰度)BMP / JPG / PPM / PGM图像。您可
手机蓝牙通信遥控无线调试神器介绍: 最近也看到论坛很多小车啊机器人项目,似乎有必要为大家提供一个完善的遥控解决方案,所以翻出这个工程小通了个宵准备填上这个遥远的坑。手机遥控蓝牙通信无线调试APP基本功能已经完成了,目前正在各大应用商店审核,下面会详细介绍一下功能和使用方法。 连接Arduino的实用调试工具,分为几个模块:提供模拟摇杆、重力感应控制,串口示波器功能,串口调试助手功能等;APP通过蓝牙连接硬件模块,附件内容提供配套Arduino库。 先看看APP的UI界面,如截图: APP是通过蓝牙连接蓝牙模块然后和Arduino交互的,点击右上角的图标连接就行(当然模块需要事先在手机设置里配对),依次介绍一下各个标签的功能: 摇杆功能: 连接Arduino后可以在程序里通过库函数读取到摇杆的数值,用于遥控小车什么的最方便啦,比如我之前的 Qbot 就是用这个遥控的 重力感应功能: 跟摇杆一样,不过这里变成摇晃手机进行控制了,依然是可以在Arduino程序里读出数据 曲线功能: 提供3个通道数据的曲线绘制功能,曲线的数据可以在Arduino库函数里进行调用发送,方便用于调节参数之类的 串口助手功能: 前面几个模式都是可以调用库函数进行方便的交互的,但是如果只想按自己的指令来操作,或者只是想有个串口显示的窗口,就可以用到这个模块,既可以发送数据也可以接收,是完全透传的 Arduino库函数的使用: 库函数的下载地址在文末,使用方法其实和之前的迹和颜艺Boy基本雷同,可以参考连接使用: 手机摄像头实时跟踪小车,附APP和Arduino源码:https://www.cirmall.com/circuit/6375/detail?3 能识别人脸表情的高仿真机器人Arduino设计:https://www.cirmall.com/circuit/6374/detail?3 不一样的是,由于前两者都只需要接收手机数据,所以可以使用软件串口来连接模块,所以可以自定义端口而且不影响程序下载;而由于软件串口在同时收发的时候会有丢包的BUG,所以在本APP中只能使用硬件串口连接(另一个原因是像曲线绘制功能需要较高的通信速率,所以硬件串口会可靠很多),这里非常建议使用带2个以上串口的Arduino板子如Mega,pro micro等,省去下载的时候拔插模块的麻烦。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值