3自由度并联绘图机器人实现写字功能(一)

news/2024/4/18 18:57:56/文章来源:https://blog.csdn.net/Robotway/article/details/130157562

1. 功能说明

    本文示例将实现R305样机3自由度并联绘图机器人写字的功能。

2. 电子硬件

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

主控板

Basra主控板(兼容Arduino Uno)

扩展板Bigfish2.1扩展板
电池7.4V锂电池

3. 功能实现

3.1建立坐标系

      我们需要先对3自由度并联绘图机器人进行极限位置调节,下图中为左极限位置,右极限位置与其对称。3自由度并联绘图机器人绘图主要由图中所示两个伺服电机控制。

3.2硬件连接

    ① 左侧舵机连接Bigfish扩展板D4号引脚

    ② 右侧舵机连接Bigfish扩展板D7号引脚

    ③ 抬笔舵机连接到Bigfish扩展板D11号引脚

3.3 示例程序

编程环境:Arduino 1.8.19

      将参考例程(_1_servoWrite.ino)下载到主控板,调试时可以先只安装舵机输出头,或者安装输出头及L1连杆,运行观察舵机转动状况。

/*------------------------------------------------------------------------------------版权说明:Copyright 2023 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved.Distributed under MIT license.See file LICENSE for detail or copy athttps://opensource.org/licenses/MITby 机器谱 2023-03-31 https://www.robotway.com/------------------------------*/#define SERVOLEFTNULL 500      //左侧舵机转动到0度的值#define SERVORIGHTNULL 500     //右侧舵机转动到0度的值#define SERVOFAKTORLEFT 603    //左侧舵机转动到0度右侧舵机转动到90度时的值#define SERVOFAKTORRIGHT 610   //左侧舵机转动到90度右侧舵机转动到180度时的值#define LIFT0 2000             //落笔写字时舵机转动的值#define LIFT1 1800             //一笔写完换笔时舵机转动的值#define LIFT2 1400             //初始及完成写字后抬笔时舵机的值#define SERVOPINLEFT 4         //定义一些舵机引脚#define SERVOPINRIGHT 7#define SERVOPINLIFT 11#define LIFTSPEED 1500         //定义抬笔落笔时舵机转动的速度#define L1 90                  //定义与舵机相连杆的长度 mm  #define L2 117.6               //定义与舵机相连杆的端点铰接处中心到笔中心的距离 mm#define L3 31.6                //定义中间杆顶端铰接处中心到笔的距离 mm#define X1 40.0                //定义左侧舵机中心轴到原点在X方向上的距离#define Y1 -42                 //定义左侧舵机中心轴到X轴的垂直距离#define X2 111.4               //定义右侧舵机中心轴到原点在X方向上的距离#define Y2 -42                 //定义右侧舵机中心轴到到X轴的垂直距离//坐标系建立第一象限,X轴方向为140mm,Y轴方向为120mm,选取坐标点时Y值建议大于70int coAry[10][10][2] = {         //汉字   王{{25,110},{0,0},{51,110},{1,1}},{{26,98},{0,0},{49,98},{1,1}},{{25,84},{0,0},{51,84},{1,1}},{{37,110},{0,0},{37,84},{1,1}},//汉字   云{{61,110},{0,0},{81,110},{1,1}},{{58,100},{0,0},{85,100},{1,1}},{{68,100},{0,0},{62,85},{86,85},{1,1}},{{80,96},{0,0},{91,82},{1,1}},//汉字   飞{{99,110},{0,0},{114,110},{114,98},{115,90},{115,86},{118,84},{121,82},{126,88},{1,1}},{{121,103},{0,0},{116,98},{122,94},{1,1}}};#include <Servo.h>int servoLift = LIFT2;Servo servo1;Servo servo2;Servo servo3;volatile double lastX = 57;   //笔初始坐标值volatile double lastY = 93;void setup() {Serial.begin(9600);        //开启串口通信/*servo1.attach(SERVOPINLEFT);servo2.attach(SERVOPINRIGHT);servo3.attach(SERVOPINLIFT);*/}void loop() {Serial.println("begin");if(1){  if(!servo1.attached()) servo1.attach(SERVOPINLEFT);if(!servo2.attached()) servo2.attach(SERVOPINRIGHT);if(!servo3.attached()) servo3.attach(SERVOPINLIFT);lift(2);//delay(1000);//汉字坐标处理for(int i=0;i<10;i++){for(int j=0;j<10;j++){int x = coAry[i][j][0];int y = coAry[i][j][1];//Serial.println(x);//Serial.println(y);if(x == 0 && y == 0){lift(0);continue;}else if(x == 1 && y == 1){lift(1);break;}drawTo(x,y);//delay(10);}}/*//摆臂测试坐标,左侧舵机转动到0度,右侧舵机转动到90度;左侧舵机转动到90度,右侧舵机转动到180度,依次循环drawTo(0,120.0);delay(1000);Serial.println("----------------------");drawTo(140.0, 120.0);delay(1000);///*/lift(2);servo1.detach();servo2.detach();servo3.detach();   Serial.println("end");}}//抬笔舵机转动函数,三个动作,落笔、换笔、起笔, 0 ,1, 2void lift(char lift){switch(lift){case 0:Serial.println("lift0");if(servoLift >= LIFT0){while(servoLift >= LIFT0){servoLift--;servo3.writeMicroseconds(servoLift);delayMicroseconds(LIFTSPEED);}}else{while(servoLift <= LIFT0){servoLift++;servo3.writeMicroseconds(servoLift);delayMicroseconds(LIFTSPEED);}}break;case 1:Serial.println("lift1");if(servoLift >= LIFT1){while(servoLift >= LIFT1){servoLift--;servo3.writeMicroseconds(servoLift);delayMicroseconds(LIFTSPEED);}}else{while(servoLift <= LIFT1){servoLift++;servo3.writeMicroseconds(servoLift);delayMicroseconds(LIFTSPEED);}}break;case 2:Serial.println("lift2");if(servoLift >= LIFT2){while(servoLift >= LIFT2){servoLift--;servo3.writeMicroseconds(servoLift);delayMicroseconds(LIFTSPEED);}}else{while(servoLift <= LIFT2){servoLift++;servo3.writeMicroseconds(servoLift);delayMicroseconds(LIFTSPEED);}}break;default:break;}}//笔移动函数,参数为点坐标值,计算两点坐标距离来控制笔移动void drawTo(double pX, double pY) {double dx, dy, c;int i;Serial.println(pX);Serial.println(pY);// dx dy of new pointdx = pX - lastX;dy = pY - lastY;//path lenght in mm, times 4 equals 4 steps per mmc = floor(1 * sqrt(dx * dx + dy * dy));if (c < 1) c = 1;for (i = 0; i <= c; i++) {// draw line point by pointset_XY(lastX + (i * dx / c), lastY + (i * dy / c));}lastX = pX;lastY = pY;}double return_angle(double a, double b, double c) {// cosine rule for angle between c and areturn acos((a * a + c * c - b * b) / (2 * a * c));}//用各种三角函数把位置坐标换算成舵机的角度,如何计算,请参考//http://www.thingiverse.com/thing:248009/void set_XY(double Tx, double Ty){delay(1);double dx, dy, c, a1, a2, Hx, Hy;// calculate triangle between pen, servoLeft and arm joint// cartesian dx/dydx = Tx - X1;dy = Ty - Y1;// polar lemgth (c) and angle (a1)c = sqrt(dx * dx + dy * dy); //a1 = atan2(dy, dx); //a2 = return_angle(L1, L2, c);//Serial.println(floor(((M_PI-a1 - a2) * SERVOFAKTORLEFT) + SERVOLEFTNULL));servo1.writeMicroseconds(floor(((M_PI-a1 - a2) * SERVOFAKTORLEFT) + SERVOLEFTNULL));// calculate joinr arm point for triangle of the right servo arma2 = return_angle(L2, L1, c);Hx = Tx + L3 * cos((a1 - a2 + 0.621) + M_PI); //36,5掳Hy = Ty + L3 * sin((a1 - a2 + 0.621) + M_PI);// calculate triangle between pen joint, servoRight and arm jointdx = Hx - X2;dy = Hy - Y2;c = sqrt(dx * dx + dy * dy);a1 = atan2(dy, dx);a2 = return_angle(L1, (L2 - L3), c);//Serial.println(floor(((M_PI - a1 + a2) * SERVOFAKTORRIGHT) + SERVORIGHTNULL));servo2.writeMicroseconds(floor(((M_PI - a1 + a2) * SERVOFAKTORRIGHT) + SERVORIGHTNULL));}

      两个舵机输出头会保持一个水平的同时另一个垂直,如上述演示视频中所示,如果差距较大,可拆下输出头进行调节,如果比较接近,可以修改程序中前四行参数的值:

      SERVOFAKTORLEFT 左侧舵机水平、右侧舵机垂直位置,数值增加顺时针调整; SERVOFAKTORRIGHT 右侧舵机水平、左侧舵机垂直位置,数值减小逆时针调整;

      SERVOLEFTNULL 左侧舵机0°位置,可不调节;

      SERVORIGHTNULL 右侧舵机0°位置,可不调节。

      当调试完成后可以安装其余连杆,此测试例程中所调节的是笔架在绘图区域中的两端位置,即左侧点(0, 120),右侧点(140, 120)。

      根据上述步骤中所调节的四个参数修改_1_servoWrite.ino例程中对应参数的值。然后将该例程下载到主控板中,运行程序即可书写汉字。程序中所存储的汉字为“王云飞”坐标,如果要书写其它字体,可按照上述3.1步骤所示建立相应坐标系,将各笔画记录到程序中即可。

      坐标系可以按如下格式建立:

      根据上面图表中可知,只要记录每一笔画的坐标值到程序中即可,字体的坐标值在程序中将以数组的形式记录。如下图所示:

      以王字的第一笔:横来说,{25,110}表示横的第一个点坐标,数组中{0,0}表示当x=0&&y=0时落笔,每一笔的第一个坐标后要添加{0,0},然后{51,110}为横的第二个点坐标,因为之前笔已经落下,所以此处将绘制此横;然后{1,1}表示当x=1&&y=1时抬笔,此时一笔写完,将执行下一行坐标。每一笔坐标用大括号括起来,因此{{25,110},{0,0},{51,110},{1,1}},表示王字的第一笔。如要写其它字体,按以上所示建立坐标系,获取坐标数据,按格式记录到程序中即可,并按笔画数量修改数组大小。

4. 资料下载

①写字-例程源代码

②写字-样机3D文件

资料内容详见:3自由度并联绘图机器人-写字

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_102261.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

远程访问及控制ssh

SSH远程管理 OpenSSH服务器 SSH(Secure Shell) 协议 是一种安全通道协议。主要用来实现字符界面的远程登录、远程复制等功能。对通信数据进行了加密处理&#xff0c;用于远程管理其中包括用户登录时输入的用户口令。因此SSH协议具有很好的安全性------------&#xff08;同样…

d2l Transformer

终于到变形金刚了&#xff0c;他的主要特征在于多头自注意力的使用&#xff0c;以及摒弃了rnn的操作。 目录 1.原理 2.多头注意力 3.逐位前馈网络FFN 4.层归一化 5.残差连接 6.Encoder 7.Decoder 8.训练 9.预测 1.原理 主要贡献&#xff1a;1.纯使用attention的Enco…

Android程序员向音视频进阶,有前景吗

随着移动互联网的普及和发展&#xff0c;Android开发成为了很多人的就业选择&#xff0c;希望在这个行业能获得自己的一席之地。然而&#xff0c;随着时间的推移&#xff0c;越来越多的人进入到了Android开发行业&#xff0c;就导致目前Android开发的工作越来越难找&#xff0c…

EFI Driver Model(下)-USB 驱动设计

1、USB简介 通用串行总线&#xff08;英语&#xff1a;Universal Serial Bus&#xff0c;缩写&#xff1a;USB&#xff09;是一种串口总线标准&#xff0c;也是一种输入输出接口的技术规范&#xff0c;被广泛地应用于个人电脑和移动设备等信息通讯产品&#xff0c;并扩展至摄影…

我看谁没看过

vue在新窗口打开页面方法 const { href } this.$router.resolve({path: "/officePlatform/addPrompt"});window.open(href, "_blank"); 添加圆形标志 h3::before {content: "";display: inline-block;width: 13px;height: 13px;background: va…

NFT介绍及监管规则

什么是NFT NFT是Non-Fungible Token&#xff08;非同质化代币&#xff09;的缩写。 NFT是“Non-Fungible Token”的缩写&#xff0c;即非同质化代币。不同于FT&#xff08;Fungible Token&#xff0c;同质化代币&#xff09;&#xff0c;每一个NFT都是独一无二且不可相互替代的…

第二章 Maven 核心程序解压和配置

第一节 Maven核心程序解压与配置 1、Maven 官网地址 首页&#xff1a; Maven – Welcome to Apache Maven(opens new window) 下载页面&#xff1a; Maven – Download Apache Maven(opens new window) 下载链接&#xff1a; 具体下载地址&#xff1a;https://dlcdn.apac…

【云原生】Java 应用程序在 Kubernetes 上棘手的内存管理

文章目录 引言JVM 内存模型简介非 Heap 内存Heap 堆内存Kubernetes 内存管理JVM 和 Kubernetes场景 1 — Java Out Of Memory 错误场景 2 — Pod 超出内存 limit 限制场景 3 — Pod 超出节点的可用内存场景 4 — 参数配置良好&#xff0c;应用程序运行良好 结语 引言 如何结合…

三月、四月总计面试碰壁15次,作为一个27岁的测试工程师.....

3年测试经验原来什么都不是&#xff0c;只是给你的简历上画了一笔&#xff0c;一直觉得经验多&#xff0c;无论在哪都能找到满意的工作&#xff0c;但是现实却是给我打了一个大巴掌&#xff01;事后也不会给糖的那种... 先说一下自己的个人情况&#xff0c;普通二本计算机专业…

JVM调优最佳参数

项目背景 C端的项目&#xff0c;用户量比较多&#xff0c;请求比较多。 启动参数表 Xmx指定应用程序可用的最大堆大小。 Xms指定应用程序可用的最小堆大小。 &#xff08;一般情况下&#xff0c;需要设置Xmx和Xms为相等的值&#xff0c;且为一个固定的值&#xff09; 如果该值…

图像处理:均值滤波算法

目录 前言 概念介绍 基本原理 Opencv实现中值滤波 Python手写实现均值滤波 参考文章 前言 在此之前&#xff0c;我曾在此篇中推导过图像处理&#xff1a;推导五种滤波算法&#xff08;均值、中值、高斯、双边、引导&#xff09;。这在此基础上&#xff0c;我想更深入地研…

使用状态机实现幂等性

文章目录 背景幂等概念适用场景示例代码上述代码状态流转 背景 在某些场景下&#xff0c;可以使用状态机来实现幂等性。将业务流程抽象为一个状态机&#xff0c;定义各个状态之间的转换规则。当收到一个请求时&#xff0c;根据当前状态和请求类型来判断是否允许执行操作&#x…

数学知识四

容斥原理 S表示面积&#xff0c;下面公式可求出不相交的面积 2个圆的公式是这样 4个圆的面积是 总面积-所有俩俩相交的面积所有三三相交的面积-四四相交的面积&#xff0c;公式里加和减互相出现。 从n个集合里面挑一个一直到从n个集合里面挑n个 1-10中&#xff0c;能被2&#x…

【 SpringBoot单元测试 和 Mybatis 增,删,改 操作 】

文章目录 一、Spring-Boot单元测试(了解)1.1 概念1.2 单元测试引用1.3 单元测试的实现1.4 简单的断言说明1.5 单元测试优点 二、Mybatis 增&#xff0c;删&#xff0c;改 操作2.1 增加⽤户操作2.2 修改⽤户操作2.3 删除⽤户操作 一、Spring-Boot单元测试(了解) 1.1 概念 单元测…

645. 错误的集合|||697. 数组的度|||448. 找到所有数组中消失的数字

645. 错误的集合 题目 集合 s 包含从 1 到 n 的整数。不幸的是&#xff0c;因为数据错误&#xff0c;导致集合里面某一个数字复制了成了集合里面的另外一个数字的值&#xff0c;导致集合 丢失了一个数字 并且 有一个数字重复 。 给定一个数组 nums 代表了集合 S 发生错误后的…

教你轻松申请Azure OpenAI

Azure OpenAI 和 OpenAI 官方提供的服务基本是一致的&#xff0c;但是目前前者还是处于预览版的状态&#xff0c;一些功能还没有完全开放。 优点&#xff1a; 不受地域限制&#xff0c;国内可以直接调用。可以自己上传训练数据进行训练&#xff08;据说很贵&#xff09;。Azu…

Cloud Kernel SIG月度动态:发布 Anolis 8.8 镜像、kABI 社区共建流程

Cloud Kernel SIG&#xff08;Special Interest Group&#xff09;&#xff1a;支撑龙蜥内核版本的研发、发布和服务&#xff0c;提供生产可用的高性价比内核产品。 01 SIG 整体进展 Anolis 8.8 镜像发布&#xff0c;默认搭载 ANCK 5.10-013 版本。 Anolis 23 滚动内核更新至…

Windows下版本控制器(SVN)-验证是否安装成功+配置版本库+启动服务器端程序

文章目录 基础知识-Windows下版本控制器(SVN)3、Subversion 安装与配置3.1 验证是否安装成功。3.2 配置版本库3.3 启动服务器端程序 基础知识-Windows下版本控制器(SVN) 3、Subversion 安装与配置 TortoiseSVN安装与配置网上资料太多了&#xff0c;这里就不阐述了。 3.1 验证是…

【Java代码】MP3、flac歌曲批量生成同名的“xxx.lrc”歌词文件导入索尼黑砖二代

目录 1、准备条件2、实现方式3、代码环境和maven依赖4、Java代码5、示例1结果6、示例2结果7、一个小问题8、“音乐标签”下载地址 1、准备条件 网易云下载的MP3、flac后缀的歌曲若干首&#xff08;ncm后缀的歌曲需要还原格式&#xff0c;不然会随着VIP过期而无法听&#xff09…

【原理图专题】案例:从集成的电平转换芯片换成三极管分立电平转换怎么就报异常

本案例是一个已经小批量量产的设备,不是我测试出来的,但是也算是我之前一手造成的,因为原理图这部分是我修改的。 异常发现最近生产的整机有部分非接读卡时无法控制到蜂鸣器发声音。我们的设计是这样的,有两个MCU互相通信,一个MCU是控制蜂鸣器的,另一个MCU通过SPI与非接芯…