机器谱

【R207舵机云台

作者:机器谱

图文展示3264(1)(1)

图文展示3264(1)(1)

副标题

概述
体感姿态跟随
追踪球形目标

2.结构说明

    该样机由一个 舵机 加一个 舵机关节模组 构成。

1.运动功能说明

      舵机云台下方的舵机可以提供一个左右摆动的动作,同时上方横置的关节模组可以提供一个上下摆动的动作。在这两部分的配合下,云台的执行端端(即:关节模组的U型支架)可以灵活地走出一个近似半球的运动轨迹。

3.运动功能实现


3.1 电子硬件

     在这个示例中,我们采用了以下硬件,请大家参考:

3.2 编写程序

编程环境:Arduino 1.8.19

舵机云台的控制关键是驱动舵机舵机关节模组

云台运动的代码(点击查看:SimultaneousMovement.ino

主控板Basra(兼容Arduino Uno)
扩展板Bigfish2.1
电池7.4V锂电池


序号

内容
1
样机3D文件
2
例程源代码


将两个舵机接在扩展板的D3以及D4舵机接口上。

4.扩展样机

    使用不同的舵机和支架,可以构建出不同形态的云台,如图所示:

5.资料清单

概述
文件下载
【整体打包】-【207】舵机云台-概述-资料下载.zip
918.78KB下载39次下载
上一页 1 下一页

体感姿态跟随

1. 功能说明

      本文示例将实现R207样机舵机云台根据 六轴陀螺仪传感器 的数据实现姿态跟随的功能。

2. 电子硬件

      在这个示例中,我们采用了以下硬件,请大家参考:

主控板

Basra主控板(兼容Arduino Uno)

扩展板

Bigfish2.1扩展板

传感器六轴陀螺仪
电池7.4V锂电池


物料

测试数据

舵机0

0   ---   180‍

舵机1

0   ---   110‍

陀螺仪的加速度包X轴数据从左到右转动陀螺仪,数据从(+1.01,-1.05)逐渐减小;中值为0;

陀螺仪的加速度包Y轴数据

沿Y轴俯仰陀螺仪时,数据从(-1.15,1.01)逐渐增大;中值为0;


/*------------------------------------------------------------------------------------

  版权说明:Copyright 2023 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved.

           Distributed under MIT license.See file LICENSE for detail or copy at

           https://opensource.org/licenses/MIT

           by 机器谱 2023-04-24 https://www.robotway.com/

  ------------------------------*/

/*   

    功能:云台可以根据陀螺仪传感器的数据实现姿态跟随

    接线:陀螺仪传感器接在扩展板的Gnd、Vcc(3.3v)、RX、TX;

          底座舵机0号接在扩展板的(Gnd、Vcc、D4);

          摆动舵机1号接在扩展板的(Gnd、Vcc、D3)

*/

#include<Servo.h>   //调用舵机库函数

#include<Math.h>

Servo myservo[2];   //声明两个舵机

int myservopin[2] = {4, 3}; // 定义舵机的引脚

#define Gyroscope_left_LimitAngle_X   -1.05   //读取到陀螺仪 X 轴向左偏的极限数值

#define Gyroscope_Right_LimitAngle_X   1.01   //读取到陀螺仪 X 轴向右偏的极限数值

#define Gyroscope_Middle_LimitAngle_X   0    //读取到陀螺仪 X 轴平放时的数值

#define Gyroscope_left_LimitAngle_Y   -1.05   //读取到陀螺仪 Y 轴向左偏的极限数值

#define Gyroscope_Right_LimitAngle_Y   1.01   //读取到陀螺仪 Y 轴向右偏的极限数值

#define Gyroscope_Middle_LimitAngle_Y   0    //读取到陀螺仪 Y 轴平放时的数值


#define Servo_One_Mix_Angle 0       //1号舵机最小角度

#define Servo_One_Max_Angle 180     //1号舵机最大角度

#define Servo_Two_Mix_Angle 0       //2号舵机最小角度

#define Servo_Two_Max_Angle 110     //2号舵机最大角度

#define Servo_Speed 10              //舵机速度


unsigned char Re_buf[11],counter=0;

unsigned char sign=0;

float a[3],w[3],angle[3],T;

int servo_angle_current[2] = {0,0};

float value_init[2]={90,90};

float f = 10.0;                     //舵机的频率


void setup()

{

   Serial.begin(115200);           //打开串口,并设置波特率为115200

   myservo[0].attach(myservopin[0]);

   myservo[1].attach(myservopin[1]);

}


void loop()

{

   Get_gyroscope_And_Control();   //根据陀螺仪传感器的数据实现姿态跟随

}

电路连接说明:

      ① 六轴陀螺仪传感器接在Bigfish扩展板的GNDVCC3.3V)、RX、TX;

      ② 底座舵机0号接在Bigfish扩展板的(GNDVCCD4);

      ③ 摆动舵机1号接在Bigfish扩展板的(GNDVCCD3)。

3. 功能实现

      编程环境:Arduino 1.8.19

      实现思路:舵机云台可以根据陀螺仪传感器的数据实现姿态跟随。

六轴陀螺仪实物与空间坐标系的对应关系:

3.1 测试数据

     ① 测试舵机云台的两个舵机初始角度,记录数据;

     ② 测试六轴陀螺仪传感器的姿态数据。

本实验中测试出的实验数据大家可参考格式,测试出自己实验数据。

3.2 示例程序

     根据已测数据编写程序,下面提供一个参考例程(body_feeling_attitude.ino):

注意:本次实验测试数据对应的程序位置如下图所示,大家可尝试输入自己的实验数据参数,修改这段程序,使舵机云台的姿态跟随更加流畅。

4. 资料清单

序号

内容
1

【R207】-体感姿态跟随-程序源代码


文件下载
【整体打包】-【R207】舵机云台-体感姿态跟随-资料附件.zip
4.93KB下载12次下载
上一页 1 下一页

追踪球形目标

1. 功能说明

      在R207样机舵机云台上安装一个摄像头,本文示例将实现舵机云台追踪球形物体的功能。

2. 电子硬件

      在这个示例中,我们采用了以下硬件,请大家参考:

/*------------------------------------------------------------------------------------

   版权说明:Copyright 2023 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved.

           Distributed under MIT license.See file LICENSE for detail or copy at

           https://opensource.org/licenses/MIT

           by 机器谱 2023-04-24 https://www.robotway.com/

   ------------------------------*/

#include <Servo.h>

#define BOTTOM_SERVO_MIN 10

#define BOTTOM_SERVO_MAX 175

#define TOP_SERVO_MIN 85

#define TOP_SERVO_MAX 175

const String CMD_UP = "U";

const String CMD_DOWN = "D";

const String CMD_LEFT = "L";

const String CMD_RIGHT = "R";

Servo myServo[2];

int servo_value[2] = {85, 105};

int port0 = 4;

int port1 = 7;

int servo_move_angle = 1;

void setup()

{

   Serial.begin(9600);

   ServoInit();

   delay(1000);

}

void loop()

{

   String s = SerialRead();

   

   if(s != "")

   {

    if(s == CMD_UP)

      ServoAdjust(port1, -servo_move_angle);

    else if(s == CMD_DOWN)

      ServoAdjust(port1, servo_move_angle);

    else if(s == CMD_LEFT)

      ServoAdjust(port0, -servo_move_angle);

    else if(s == CMD_RIGHT)

      ServoAdjust(port0, servo_move_angle);

   }

}

String SerialRead()

{

   String str = "";

   while(Serial.available())

   {

    str += char(Serial.read());

   }

   return str;

}

void ServoInit()

{

   myServo[0].attach(port0);

   myServo[1].attach(port1);

   

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

   {

    myServo[i].write(servo_value[i]);

   }

}

void ServoAdjust(int which, int where)

{

   switch(which)

   {

    case 4:

      servo_value[0] += where;

     

      if(servo_value[0] <= BOTTOM_SERVO_MIN)

        servo_value[0] = BOTTOM_SERVO_MIN;

      else if(servo_value[0] >= BOTTOM_SERVO_MAX)

        servo_value[0] = BOTTOM_SERVO_MAX;

     

      myServo[0].write(servo_value[0]);

      break;

    case 7:

      servo_value[1] += where;

     

      if(servo_value[1] <= TOP_SERVO_MIN)

        servo_value[1] = TOP_SERVO_MIN;

      else if(servo_value[1] >= TOP_SERVO_MAX)

        servo_value[1] = TOP_SERVO_MAX;

     

      myServo[1].write(servo_value[1]);

      break;

    default:

      break;

   }

}

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using System.Windows.Navigation;

using System.Windows.Shapes;

using System.Windows.Forms;

using System.Runtime.InteropServices;

using System.Threading;

using System.Net;

using System.Net.Sockets;


namespace Project

{

    /// <summary>

    /// 形状跟踪,球

    /// </summary>

    public partial class MainWindow : Window

    {

        //导入 HoughCircles.dll 动态链接库

        [DllImport("HoughCircles_DLL")]

        public static extern void HoughCircles([MarshalAs(UnmanagedType.LPStr)]string ip_address, //视频地址

                                                                                    ref int xpos, //跟踪物体中心X坐标

                                                                                    ref int ypos); //跟踪物体中心Y坐标


        //定义窗口大小

        int cap_w = 320, cap_h = 240;

        //跟踪物体中心 x, y 坐标值,物体轮廓半径r

        int x = 0, y = 0;

        //定义命令变量

        string CMD_UP = "", CMD_DOWN = "", CMD_TURN_LEFT = "", CMD_TURN_RIGHT = "";

        //结构体

        public struct Boundaries

        {

            public int x_left;

            public int x_right;

            public int y_up;

            public int y_down;

        }

        Boundaries boundaries = new Boundaries();


        public MainWindow()

        {

            InitializeComponent();

        }


        private void Window_Loaded(object sender, RoutedEventArgs e)

        {

            GetIni();

            SetPosition();

            CmdInit();

            StructInit();

        }


        //变量初始化

        private void CmdInit()

        {

            CMD_UP = "U";

            CMD_DOWN = "D";

            CMD_TURN_LEFT = "L";

            CMD_TURN_RIGHT = "R";

        }


        //结构体初始化

        private void StructInit()

        {

            boundaries.x_left = 100;

            boundaries.x_right = 200;

            boundaries.y_up = 80;

            boundaries.y_down = 160;

        }


        //获取ini配置文件信息

        private void GetIni()

        {

            ini_RW.FileName = System.Windows.Forms.Application.StartupPath + "\\Config.ini";

            this.videoAddress.Text = ini_RW.ReadIni("VideoUrl", "videourl", "");

            this.ipAddress.Text = ini_RW.ReadIni("ControlUrl", "controlUrl", "");

            this.portBox.Text = ini_RW.ReadIni("ControlPort", "controlPort", "");

        }


        //修改配置

        private void setBtn_Click(object sender, RoutedEventArgs e)

        {

            ini_RW.WriteIni("VideoUrl", "videourl", this.videoAddress.Text);

            ini_RW.WriteIni("ControlUrl", "controlUrl", this.ipAddress.Text);

            ini_RW.WriteIni("ControlPort", "controlPort", this.portBox.Text);


            System.Windows.MessageBox.Show("配置成功!请重启程序以使配置生效。", "配置信息", MessageBoxButton.OK, MessageBoxImage.Information);

            //this.Close();

        }


        //命令发送函数

        void SendData(string data)

        {

            try

            {

                IPAddress ips = IPAddress.Parse(ipAddress.Text.ToString());//("192.168.8.1");

                IPEndPoint ipe = new IPEndPoint(ips, Convert.ToInt32(portBox.Text.ToString()));//把ip和端口转化为IPEndPoint实例

                Socket c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建一个Socket


                c.Connect(ipe);//连接到服务器


                byte[] bs = Encoding.ASCII.GetBytes(data);

                c.Send(bs, bs.Length, 0);//发送测试信息

                c.Close();

            }

            catch (Exception e)

            {

                System.Windows.Forms.MessageBox.Show(e.Message);

            }

        }


        //跟踪物体位置界限判断

        private void LineDetect(int _x, int _y)

        {

            if (_x > 0 && _x <= boundaries.x_left)

            {

                SendData(CMD_TURN_LEFT);

            }

            else if (x > boundaries.x_right && x < cap_w)

            {

                SendData(CMD_TURN_RIGHT);

            }

            else if (_y > 0 && _y <= boundaries.y_up)

            {

                SendData(CMD_DOWN);

            }

            else if (_y > boundaries.y_down && _y < cap_h)

            {

                SendData(CMD_UP);

            }

        }


        //物体位置初始化#FFACAAAA

        private void SetPosition()

        {

            var color = new SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#00008B"));

            objEllipse.Height = 30;

            objEllipse.Width = 30;

            objEllipse.Fill = color;


            var left_distance = (cap_w - objEllipse.Width) / 2;

            var top_distance = (cap_h - objEllipse.Height) / 2;


            Canvas.SetLeft(objEllipse, left_distance);

            Canvas.SetTop(objEllipse, top_distance);

        }


        //跟踪物体位置更新函数

        private void PositionUpdate(int x, int y)

        {

            LineDetect(x, y);


            Canvas.SetLeft(objEllipse, x);

            Canvas.SetTop(objEllipse, y);


            posLable.Content = x + " , " + y;

        }


        //线程函数

        private void ThreadCapShow()

        {

            try

            {

                while (true)

                {

                    this.Dispatcher.Invoke(

                        new Action(

                            delegate

                            {

                                string ip = this.videoAddress.Text;

                                HoughCircles(ip, ref x, ref y);

                                PositionUpdate(x - 15, y - 15);

                            }

                            ));

                }


            }

            catch { };

        }


        //打开跟踪窗口

        private void openBtn_Click(object sender, RoutedEventArgs e)

        {

            try

            {

                Thread m_thread = new Thread(ThreadCapShow);

                m_thread.IsBackground = true;

                m_thread.Start();

            }

            catch { };

        }

    }

}

电路连接说明:

      ① 将2510通信转接板连接到Bigfish扩展板的扩展坞上面;

      ② 用3根母对母杜邦线将2510通信转接板与WiFi路由器连接起来:GND-GND、RX-RX、TX-TX;

      ③ 找到1根USB线,一端连接到2510通信转接板接口上,另一端连接到WiFi路由器USB接口上;

      ④ 将摄像头线连接到WiFi路由器接口上。

3. 功能实现

   实现思路:实现舵机云台追踪蓝色小球。

3.1 工作原理

   ① 摄像头采集图像信息;

   ② 通过WiFi将图像信息传递给PC端(VS2015配置的OpenCV环境);

   ③ 在PC端使用OpenCV对图像转化为灰度图像;

   ④ 检测圆形,并且计算出圆中心坐标;

   ⑤ 采用九宫格方式对摄像显示图像进行分割;

   ⑥ 确定目标物体在显示图像的所处九宫格位置;

   ⑦ 如果目标图像超出九宫格位置的中心,调整摄像头矫正偏移使目标物体在屏幕中心位置;

   ⑧ 调整摄像头需要上位机通过WiFi给下位机发送矫正指令,下位机需要接收信号,并且让安装了摄像头的舵机云台做出相应的矫正动作。

3.2 示例程序

     编程环境:Arduino 1.8.19

① 下位机例程

      将参考例程(example.ino)下载到主控板,开启路由器,将路由器与主控板TX、Rx串口进行连接,同时将PC连接至路由器WIFI网络。下位机接收上位机处理的图像信息结果控制舵机云台相应运动,云台跟随目标物体运动。

② 上位机例程

     下面提供一个可以实现舵机云台追踪球形物体的参考例程(MainWindow.xaml.cs),大家可参考演示视频完成该实验。

4. 资料清单

序号

内容
1

【R207】-追踪球形目标-例程源代码

2
【R207】-追踪球形目标-样机3D文件


文件下载
【整体打包】-【R207】舵机云台-追踪球形目标-资料附件.zip
42.86MB下载2次下载
上一页 1 下一页
© 2022 机器时代(北京)科技有限公司  版权所有
机器谱——机器人共享方案网站
学习  开发  设计  应用