×

使用可教机器人工智能来控制任何东西

消耗积分:0 | 格式:zip | 大小:0.00 MB | 2023-06-15

分享资料个

描述

注意:我已经清理了代码并升级了库,还创建了一个可以在您的计算机上运行的本地版本。查看Github 存储库。

Teachable Machine是谷歌开发的一款基于网络的人工智能工具,可以让你在没有任何人工智能知识的情况下训练和使用人工智能模型。用于假人的 AI 工具。整洁,对吧?

但它可以做的不仅仅是简单地在网络浏览器中展示机器学习吗?它也可以是一个实用的工具吗?

有趣的是,Teachable Machine 网站上有一个名为Tiny Sorter的演示,它使用p5.js (在线 JavaScript 编辑器/编译器)与带有伺服的 Arduino Leonardo 对话。所以完全有可能在你的电脑上运行 AI 并做一些有用的事情。

本教程是关于如何让 Teachable Machine AI 将其识别结果输出到外部设备,例如微控制器。我的方法和 Tiny Sorter 演示的方法不一样,但是原理是相似的。这对于那些对人工智能知之甚少但有兴趣将其用于他们的创客或物理计算项目的人来说尤其有用。

(注意:以下步骤仅在 Windows 10 上测试。)

这种方法的优点:

无需人工智能知识

快速、简单和免费的模型训练/托管

几乎不需要安装任何东西

如果您已经有电脑,成本相当低

只要您知道如何对它们进行编程以读取串行输入并执行操作,就可以在任何微控制器上使用

这种方法的缺点:

必须在您的计算机上进行识别,从而减少微控制器的范围/移动性

电脑需要互联网连接

人工智能模型有局限性,可能会得到错误的读数,无法进一步定制

在微控制器端调试可能更困难

一些人工智能专家可能会告诉你这很可爱,但不是真的。是的,好吧...

第 1 步:生成并上传您的 AI 模型

当你训练你的模型时,我会使用 0 类作为背景图像(什么都没有),然后要识别的东西会被命名为“1”、“2”、“3”……等等。这将使设备更容易读取结果。

对于图像识别,您可以移动对象以提高 AI 准确性,并且每个对象之间应该有足够的差异。

pYYBAGNoeZGAPKf3AADPAi9apTw588.jpg

或者,如果您正在训练声音识别模型,请确保首先输入足够的背景噪声样本。和上面一样,我会把要识别的声音命名为“1”、“2”、“3”......

pYYBAGNoeZSAZpVIAADRX6l8wSw011.jpg

模型完成训练后,单击导出模型而不是选择Tensorflow.js ->上传。完成后复制模型链接。(目前声音识别只能选择 Tensorflow.js。)

poYBAGNoeZaAHNn8AACvIkBtaCU623.jpg

第 2 步:准备 p5.js 脚本

p5.j​​s 脚本模板可以在这里找到:

图像识别:https ://editor.p5js.org/krantas/sketches/IKUf43rB

声音识别:https ://editor.p5js.org/krantas/sketches/3wZ9hAwG

或者你可以在这里找到完整的代码。手势识别版我没做过,不过应该很容易修改。

这个脚本基本上是 Teachable Machine 和 p5.js 的示例代码的组合。总共有4个文件:

sketch.js(主要代码)

index.html(导入库)

样式.css

p5.serialport.js(串口功能)

您可以登录 p5.js 并复制/保存您的脚本。您只需要更改两个地方

计算机上微控制器的串行端口(参见步骤 4)

您的模型的链接(步骤 1)

pYYBAGNoeZqALOheAADJSdzxWHo828.jpg

注意:稍后我会看看是否可以将这两个代码都更新到新的 p5.js 1.0。

记得把 COM__ 改成你的串口!

第 3 步:对您的微控制器进行编程

您的设备(在本例中为 BBC micro:bit)将需要自己的程序才能读取串行输入并对其进行处理。

串行输出是字符串或字符,没有换行符(如 \r\n)。

以下示例是通过点亮我的 BBC micro:bit 上的不同 LED 来指示接收到的图像识别结果:

结果 1(BPI:bit ESP32 板)- 红色 LED(引脚 0)

结果 2(带屏蔽的 Arduino Nano 33 IoT)- 绿色 LED(引脚 1)

结果 3(Adafruit Metro M4 Express)- 蓝色 LED(引脚 2)

结果 0(仅背景) - 白色 LED(引脚 8)

串口输出波特率为 9600。由于 micro:bit 的默认速率是 115200,所以我不得不一开始就重新设置它。

 

let result = ""
serial.redirect(
    SerialPin.USB_TX,
    SerialPin.USB_RX,
    BaudRate.BaudRate9600
)

basic.forever(function () {
    result = serial.readString()
    if (result == "0") {
        pins.digitalWritePin(DigitalPin.P0, 0)
        pins.digitalWritePin(DigitalPin.P1, 0)
        pins.digitalWritePin(DigitalPin.P2, 0)
        pins.digitalWritePin(DigitalPin.P8, 1)
    } else if (result == "1") {
        pins.digitalWritePin(DigitalPin.P0, 1)
        pins.digitalWritePin(DigitalPin.P1, 0)
    pins.digitalWritePin(DigitalPin.P2, 0)
        pins.digitalWritePin(DigitalPin.P8, 0)
    } else if (result == "2") {
        pins.digitalWritePin(DigitalPin.P0, 0)
        pins.digitalWritePin(DigitalPin.P1, 1)
        pins.digitalWritePin(DigitalPin.P2, 0)
        pins.digitalWritePin(DigitalPin.P8, 0)
    } else if (result == "3") {
        pins.digitalWritePin(DigitalPin.P0, 0)
        pins.digitalWritePin(DigitalPin.P1, 0)
        pins.digitalWritePin(DigitalPin.P2, 1)
        pins.digitalWritePin(DigitalPin.P8, 0)
    }
})

 

pYYBAGNoeZ2APPuQAAGCsCd6N0c573.png

第 4 步:连接设备的串行端口

下载并解压p5.js串口控制程序。将您的设备连接到 USB 并运行p5.serialcontrol.exe (适用于 Windows)。您可能必须将其设置为允许在您的防病毒程序中运行。

程序启动后,打开设备的串行端口。如果您不确定,请打开设备管理器以查看它具有哪个 COM 端口。

当您需要将代码闪存到板上时,请记住关闭 p5.serialcontrol 中的 COM 端口!否则会被屏蔽。

pYYBAGNoeZ-AIw7wAABxvf-VwXU959.jpg

pYYBAGNoeaGAXFnkAAAoHbCfm5A022.jpg

在 p5.js 草图中连接并设置串口后,一切都会好起来的。

第 5 步:利用 AI 的力量!

返回 p5.js 脚本编辑器并单击运行。片刻之后,脚本旁边会出现一个网络摄像头窗口。您可能会看到设备的串口灯闪烁,表示它接收到的数据。

如果您忘记打开串口,则不会发生任何错误。p5.j​​s 脚本将照常运行。

在下面的演示中,我确实可以将图像识别结果发送到我的 micro:bit:

这里的另一个演示是使用 Arduino Nano 和迷你伺服来指示声音识别结果:(背景噪音不是结果。只有当模型识别到某些东西时才会返回结果。)

结果 1(弹指) - 转为 0 度

结果 2(鼓掌)——转身 180 度

 

#include 

Servo myservo;
char result;

void setup() {
    Serial.begin(9600);
    myservo.attach(9);
    myservo.write(90);
}

void loop() {
    while (Serial.available() > 0) {
        result = Serial.read();
        switch (result) {
            case '1':
                myservo.write(0);
                break;
            case '2':
                myservo.write(180);
                break;
        }
    }
    delay(100);
}

 

我在最后添加了一个小延迟,因为伺服需要一些时间来完成它的转动。

下面是基于 3 个标签控制两个 LED 的 Arduino 代码。

 

char result = '0';

void setup() {
  Serial.begin(9600);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
}

void loop() {
  if (Serial.available() > 0) {
    result = Serial.read();
  }
  switch (result) {
    case '1':
      digitalWrite(7, HIGH);
      digitalWrite(8, LOW);
      break;
    case '2':
      digitalWrite(7, LOW);
      digitalWrite(8, HIGH);
      break;
    default:
      digitalWrite(7, LOW);
      digitalWrite(8, LOW);
  }
}

 

远程控制的可能性?

可以控制不直接连接到计算机的东西。一种可能的方法是使用微控制器上的 HC-05 蓝牙模块作为无线串口。

如果您使用的是 micro:bit,您可以使用一个简单地通过“无线电”功能将结果重新发送给其他人。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"//m.obk20.com/www/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.obk20.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'使用可教机器人工智能来控制任何东西',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"https://www.elecfans.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);