开源六轴协作机械臂myCobot280实现交互式乘法!让学习充满乐趣
本文经作者Fumitaka Kimizuka 授权我们翻译和转载。
原文链接:myCobotに「頷き」「首振り」「首傾げ」をしてもらう 🤖 - みかづきブログ・カスタム
引言
Fumitaka Kimizuka 创造了一个乘法表系统,帮助他的女儿享受学习乘法表的乐趣。她可以口头回答乘法问题,显示的数字就是乘积。如果她回答正确,myCobot 就会点头;如果她回答错误,myCobot 就会做出不同的动作。以下是作者对该系统开发过程的记录。


🤖
https://twitter.com/i/status/1793416553867706459
在实施这一机制时,我用 Node.js 编写了一个程序,让 myCobot "点头"、"摇头 "和 "歪头"。
https://twitter.com/i/status/1780785823220224188
这是我将其与 LINE Bot 相关联时创建的程序的改进版。
准备工作
首先,按照以下步骤使 myCobot 可以通过 Python 运行。
然后,使用 Node.js 和 Express 架设网络服务器。虽然你也可以使用 Python 设置网络服务器,但以我的技术水平,Node.js 对我来说更快。因此,我使用 Node.js 和 python-shell 来控制 myCobot。
python-shell - npm
.env
# Specify the USB port to which myCobot is connected
MY_COBOT_PORT=/dev/cu.XXXXXXXX
app.js (Excerpt)
const express = require('express');const express = require('express');
const { PythonShell } = require('python-shell');
const app = express();
const http = require('http').Server(app);app.use(express.json());
app.use('/', express.static(`${ __dirname }/public`));async function move(color = [255, 255, 255], angles = [0, 0, 0, 0, 0, 0], interval = 200) {return new Promise((resolve, reject) => {PythonShell.runString(`from pymycobot.mycobot import MyCobot; MyCobot('${ process.env.MY_COBOT_PORT }').set_color(${ color }); from pymycobot.mycobot import MyCobot; MyCobot('${ process.env.MY_COBOT_PORT }').send_angles([${ angles }], ${ duration })`,null).then(() => {setTimeout(() => resolve(), interval);}).catch(() => {reject();});});
}move([255, 255, 255], // LED matrix colors (RGB)[0, 0, 0, 0, 0, 0], // Angles of myCobot's joints (degrees)200
);
通过创建一个 "move "函数,该函数可以接受 LED 矩阵颜色、关节角度和驱动时间等参数,因此变得非常方便。
实施:
对于点头、摇头和歪头,请使用之前创建的`move`函数。
// Nodding
async function doYes() {return new Promise(async (resolve, reject) => {const interval = 200;try {await move([0, 0, 255], [0, 0, 0, 45, 0, 0], interval);await move([0, 0, 255], [0, 0, 0, 0, 0, 0], interval);await move([0, 0, 255], [0, 0, 0, 45, 0, 0], interval);await move([0, 0, 255], [0, 0, 0, 0, 0, 0], interval);await move([0, 0, 255], [0, 0, 0, 45, 0, 0], interval);await move([0, 0, 255], [0, 0, 0, 0, 0, 0], interval);await move([255, 255, 255], [0, 0, 0, 0, 0, 0], interval);resolve();} catch (err) {console.error(err);reject();}});
}// Shaking its head
async function doNo() {return new Promise(async (resolve, reject) => {const interval = 400;try {await move([255, 0, 0], [0, 0, 0, 0, 45, 0], interval / 2);await move([255, 0, 0], [0, 0, 0, 0, -45, 0], interval);await move([255, 0, 0], [0, 0, 0, 0, 45, 0], interval);await move([255, 0, 0], [0, 0, 0, 0, -45, 0], interval);await move([255, 0, 0], [0, 0, 0, 0, 0, 0], interval / 2);await move([255, 255, 255], [0, 0, 0, 0, 0, 0], interval / 2);resolve();} catch (err) {console.error(err);reject();}});
}// Tilting its head
async function doHmm() {return new Promise(async (resolve, reject) => {const interval = 400;try {await move([255, 0, 255], [0, 0, 0, 0, 45, 0], interval / 2);await move([255, 0, 255], [0, 0, 0, 0, 45, 0], interval);await move([255, 0, 255], [0, 0, 0, 0, 45, 0], interval);await move([255, 0, 255], [0, 0, 0, 0, -45, 0], interval);await move([255, 0, 255], [0, 0, 0, 0, 0, 0], interval / 2);await move([255, 255, 255], [0, 0, 0, 0, 0, 0], interval / 2);resolve();} catch (err) {console.error(err);reject();}});
}
我是这样实现的,接下来,通过 Web API 调用点头、摇头和歪头动作。
app.js
require('dotenv').config();const express = require('express');
const { PythonShell } = require('python-shell');
const app = express();
const http = require('http').Server(app);const PORT = 3000;app.use(express.json());
app.use('/', express.static(`${ __dirname }/public`));app.post('/yes', (req, res) => {doYes();res.send(200);
});app.post('/no', (req, res) => {doNo();res.send(200);
});app.post('/hmm', (req, res) => {doHmm();res.send(200);
});// https://www.elephantrobotics.com/wp-content/uploads/2021/03/myCobot-User-Mannul-EN-V20210318.pdf
async function move(color = [255, 255, 255], angles = [0, 0, 0, 0, 0, 0], interval = duration) {return new Promise((resolve, reject) => {PythonShell.runString(`from pymycobot.mycobot import MyCobot; MyCobot('${ process.env.MY_COBOT_PORT }').set_color(${ color }); from pymycobot.mycobot import MyCobot; MyCobot('${ process.env.MY_COBOT_PORT }').send_angles([${ angles }], ${ duration })`,null).then(() => {setTimeout(() => resolve(), interval);}).catch(() => {reject();});});
}async function doYes() {return new Promise(async (resolve, reject) => {const interval = 200;try {await move([0, 0, 255], [0, 0, 0, 45, 0, 0], interval);await move([0, 0, 255], [0, 0, 0, 0, 0, 0], interval);await move([0, 0, 255], [0, 0, 0, 45, 0, 0], interval);await move([0, 0, 255], [0, 0, 0, 0, 0, 0], interval);await move([0, 0, 255], [0, 0, 0, 45, 0, 0], interval);await move([0, 0, 255], [0, 0, 0, 0, 0, 0], interval);await move([255, 255, 255], [0, 0, 0, 0, 0, 0], interval);resolve();} catch (err) {console.error(err);reject();}});
}async function doNo() {return new Promise(async (resolve, reject) => {const interval = 400;try {await move([255, 0, 0], [0, 0, 0, 0, 45, 0], interval / 2);await move([255, 0, 0], [0, 0, 0, 0, -45, 0], interval);await move([255, 0, 0], [0, 0, 0, 0, 45, 0], interval);await move([255, 0, 0], [0, 0, 0, 0, -45, 0], interval);await move([255, 0, 0], [0, 0, 0, 0, 0, 0], interval / 2);await move([255, 255, 255], [0, 0, 0, 0, 0, 0], interval / 2);resolve();} catch (err) {console.error(err);reject();}});
}async function doHmm() {return new Promise(async (resolve, reject) => {const interval = 400;try {await move([255, 0, 255], [0, 0, 0, 0, 45, 0], interval / 2);await move([255, 0, 255], [0, 0, 0, 0, 45, 0], interval);await move([255, 0, 255], [0, 0, 0, 0, 45, 0], interval);await move([255, 0, 255], [0, 0, 0, 0, -45, 0], interval);await move([255, 0, 255], [0, 0, 0, 0, 0, 0], interval / 2);await move([255, 255, 255], [0, 0, 0, 0, 0, 0], interval / 2);resolve();} catch (err) {console.error(err);reject();}});
}try {doYes();
} catch(err) {console.error(err);
}http.listen(PORT, '0.0.0.0');
有了这个设置、
向 `http://localhost:3000/yes` 发送 POST 请求会让它点头。
向 `http://localhost:3000/no` 发送 POST 请求会让它摇头。
向 `http://localhost:3000/hmm` 发送 POST 请求会让它歪头。
将执行相应的操作。
DEMO
点头

摇头

歪着头

LED 矩阵的颜色也在悄然改变。
目前看起来是这样的,但如果再调整一下,效果可能会更好,尤其是头部的倾斜动作。
Github 存储库
https://github.com/kimizuka/mycobot-express/tree/example/timas-table
总结
我们非常感谢 Fumitaka Kimizuka 允许我们分享如此出色的技术案例研究。我们希望在阅读本文后,您能从中受到启发,创造出更多有趣而实用的项目。如果您有类似的想法或作品,请与我们分享,让我们共同推动技术进步和创新!
相关文章:
开源六轴协作机械臂myCobot280实现交互式乘法!让学习充满乐趣
本文经作者Fumitaka Kimizuka 授权我们翻译和转载。 原文链接:myCobotに「頷き」「首振り」「首傾げ」をしてもらう 🤖 - みかづきブログ・カスタム 引言 Fumitaka Kimizuka 创造了一个乘法表系统,帮助他的女儿享受学习乘法表的乐趣。她可以…...
[C++][CMake][嵌套的CMake]详细讲解
目录 0.前言 & 准备1.节点关系2.添加子目录3.解决问题1.根目录2.calc目录3.sort目录4.calc_test目录5.sort_test 4.注意 0.前言 & 准备 如果项目很大,或者项目中有很多的源码目录,在通过CMake管理项目的时候如果只使用一个CMakeLists.txt&#…...
尚品汇-(十三)
(1)查询sku列表 在ManageService 中添加 /*** SKU分页列表* param pageParam* return*/ IPage<SkuInfo> getPage(Page<SkuInfo> pageParam);接口实现类 Override public IPage<SkuInfo> getPage(Page<SkuInfo> pageParam) {Qu…...
python小练习04
三国演义词频统计与词云图绘制 import jieba import wordcloud def analysis():txt open("三国演义.txt",r,encodingutf-8).read()words jieba.lcut(txt)#精确模式counts {}for word in words:if len(word) 1:continueelif word "诸葛亮" or word &q…...
小试牛刀-Solana合约账户详解
目录 一.Solana 三.账户详解 3.1 程序账户 3.2 系统所有账户 3.3 程序派生账户(PDA) 3.4 Token账户 四、相关学习文档 五、在线编辑器 Welcome to Code Blocks blog 本篇文章主要介绍了 [Solana合约账户详解] ❤博主广交技术好友,喜欢文章的可以关注一下❤ …...
Spring Boot+Vue项目从零入手
Spring BootVue项目从零入手 一、前期准备 在搭建spring bootvue项目前,我们首先要准备好开发环境,所需相关环境和软件如下: 1、node.js 检测安装成功的方法:node -v 2、vue 检测安装成功的方法:vue -V 3、Visu…...
Vue+Xterm.js+WebSocket+JSch实现Web Shell终端
一、需求 在系统中使用Web Shell连接集群的登录节点 二、实现 前端使用Vue,WebSocket实现前后端通信,后端使用JSch ssh通讯包。 1. 前端核心代码 <template><div class"shell-container"><div id"shell"/>&l…...
用 adb 来模拟手机插上电源和拔掉电源的情形
实用的 ADB 命令 要模拟手机从 USB 充电器上拔掉的情形,你可以使用: adb shell dumpsys battery set usb 0或者,如果你使用的是 Android 6.0 或更高版本的设备,你可以使用: adb shell dumpsys battery unplug要重新…...
【SPIE独立出版】第四届智能交通系统与智慧城市国际学术会议(ITSSC 2024)
第四届智能交通系统与智慧城市国际学术会议(ITSSC 2024)将于2024年8月23-25日在中国西安举行。本次会议主要围绕智能交通、交通新能源、无人驾驶、智慧城市、智能家居、智能生活等研究领域展开讨论, 旨在为该研究领域的专家学者们提供一个分享…...
【Unity数据交互】如何Unity中读取Ecxel中的数据
👨💻个人主页:元宇宙-秩沅 👨💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨💻 本文由 秩沅 原创 👨💻 专栏交流🧧&…...
基于深度学习LightWeight的人体姿态检测跌倒系统源码
一. LightWeight概述 light weight openpose是openpose的简化版本,使用了openpose的大体流程。 Light weight openpose和openpose的区别是: a 前者使用的是Mobilenet V1(到conv5_5),后者使用的是Vgg19(前10…...
SpringBoot 生产实践:没有父 starter 的打包问题
文章目录 前言一、搜索引擎二、Chat GPT三、官方文档四、小结推荐阅读 前言 今天刚准备写点文章,需要 SpringBoot 项目来演示效果。一时心血来潮,没有采用传统的方式(即通过引入 spring-boot-starter-parent 父工程的方式)。 &l…...
IDEA配Git
目录 前言 1.创建Git仓库,获得可提交渠道 2.选择本地提交的项目名 3.配置远程仓库的地址 4.新增远程仓库地址 5.开始进行commit操作 6.push由于邮箱问题被拒绝的解决方法: 后记 前言 以下操作都是基于你已经下载了Git的前提下进行的,…...
51单片机STC89C52RC——14.1 直流电机调速
目录 目的/效果 1:电机转速同步LED呼吸灯 2 通过独立按键 控制直流电机转速。 一,STC单片机模块 二,直流电机 2.1 简介 2.2 驱动电路 2.2.1 大功率器件直接驱动 2.2.2 H桥驱动 正转 反转 2.2.3 ULN2003D 引脚、电路 2.3 PWM&…...
AI对于高考和IT行业的深远影响
目录 AI对IT行业的冲击及深远影响1. 工作自动化2. 新的就业机会3. 行业融合4. 技术升级和创新5. 数据的重要性 IT行业的冬天要持续多久?大学的软件开发类专业是否还值得报考?其他问题IT行业是否都是加班严重?35岁后就业困难是否普遍现象&…...
C语言下的文件详解
主要内容 文件概述文件指针文件的打开与关闭文件的读写 文件 把输入和输出的数据以文件的形式保存在计算机的外存储器上,可以确保数据能随时使用,避免反复输入和读取数据 文件概述 文件是指一组相关数据的有序集合 文件是存储数据的基本单位&#…...
Oracle PL / SQL块结构
在PL / SQL中,最小的有意义的代码分组被称为块。 块代码为变量声明和异常处理提供执行和作用域边界。 PL / SQL允许您创建匿名块和命名块。 命名块可以是包,过程,函数,触发器或对象类型。 PL / SQL是SQL的过程语言扩展&#x…...
MySQL的安装和启动
安装 版本 1,社区版:免费,不提供任何技术支持 2,商业版:可以试用30天,官方提供技术支持下载 1,下载地址:https://dev.mysql.com/downloads/mysql/ 2,安装:傻…...
Prometheus概述
1.什么是prometheus Prometheus 是一个开源的服务监控系统和时序数据库,其提供了通用的数据模型和快捷数据采集、存储和查询接口。它的核心组件Prometheus server会定期从静态配置的监控目标或者基于服务发现自动配置的自标中进行拉取数据,当新拉取到的…...
【SQL】什么是最左前缀原则/最左匹配原则
最左前缀原则(或最左匹配原则)是关系型数据库在使用复合索引时遵循的一条重要规则。该原则指的是,当查询条件使用复合索引时,查询优化器会首先使用索引的最左边的列,依次向右匹配,直到不再满足查询条件为止…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...
消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...
