資料介紹
描述
介紹:
根據美國國立衛生研究院的說法,“健忘可能是衰老的正常部分。” 最重要的是,老年人也經常隨著年齡的增長而面臨身體衰退。這些問題會導致一些問題,從忘記物品在哪里,到在獲取藥品或手杖等基本物品時體力消耗。
到目前為止,機器人護理已經作為寵物產品進入老年人市場,以類似的硬件和成本,我們實際上可以構建機器人來為老年人做更多的事情。在本文中,我們將討論如何使用Lego Mindstorm EV3機器人幫助老年人存儲和取物。
第 1 步:構建 GRIPP3R
MindStorm EV3 的 GRIPP3R 似乎是處理此類任務的最理想機器人,因為我們可以構建機器人并用它來抓取物體。使用樂高 MindStorm 套裝搭建機器人大約需要 2-3 小時,但實際上只需要說明書的前 68 頁,因為其他所有內容都非常美觀。
機器人完全建成后,我們首先需要測試一些基礎知識以確保其正常運行。我們可以在https://www.lego.com/en-us/themes/mindstorms/downloads下載 MindStorms Home并使用基本功能。我們的第一個測試是看看我們正在嘗試做的事情是否可能,下面是我們編寫的一個簡單的小程序,用來抓取東西,轉身走開。
運行此程序時,您應該看到下圖,計算機運行程序需要接線,我們最終產品不需要接線。現在完成了,我們可以進入下一步。
第 2 步:準備好開發環境
Alexa gadget 編寫了有關如何將 Alexa 與 Mindstorm 連接的完整設置指南,我們將只強調這一步的主要部分,強烈建議您通過那里設置環境。
設置GRIPP3R 端
在這一步中,我們使用 Visual Studio Code 和 EV3DEV 環境設置樂高頭腦風暴環境。具體要了解的東西很少。
如果磚面朝下,USB 端口和 sd 卡位于積木的左側,如果面向您,則位于機器人的左側。這花了一點時間來弄清楚。
我們現在可以插入 SD 卡并啟動 EV3,我們可以從 ev3dev 菜單設置 WiFi 網絡。
這將允許我們將 Visual Studio Code 直接連接到 ev3,而不是使用 USB 線。連接后請記住我們稍后可能需要的 ip,確保您的計算機與 ev3 磚在同一網絡上。
在 Mac/PC 端設置
我們需要可以在下載的 Microsoft VS Code。 您可以打開alexa-gadgets-mindstorms
文件夾以安裝ev3dev-browser擴展,如AlexaGadget的環境設置指南中所述
單擊顯示推薦后,它應顯示在左側,如下所示。
我們可以啟動一個名為grapp3r helper 的新工作區,并有一些空文件,或者只是從源代碼下載我的代碼。現在我們將做GRIPP3R端,我們可以連接到wifi而不是做USB編程。單擊此處連接我的設備后,應該會顯示 ev3dev,如果沒有,您可以通過“我沒有看到我的設備”手動輸入 ip
單擊瀏覽器上的下載按鈕以測試它是否有效。如果它正常工作,所有東西都應該加載到 ev3 磚中,我們都準備好進行環境設置了。
由于我們將使用藍牙來控制設備,因此我們也在這里啟用藍牙。
第 3 步:準備 Alexa 語音服務
這一步緊跟 alexagadget 的使命 1 ,我建議您仔細閱讀該指南,讓您的積木準備好響應 Alexa 的呼叫。我們將通過總結。
我們首先需要亞馬遜開發者賬號。如果您還沒有開發者帳戶,請注冊一個。我們需要在Alexa Voice Service 中創建一個產品。
保持簡單,讓我們使用與來自 alexagadget 的 Mission 1 相同的產品來創建產品。
- 名稱:頭腦風暴 EV3
- 產品編號:EV3_01
- 產品類型:Alexa小工具
- 產品類別:Animatronic 或 Figure
- 產品描述:隨心所欲
- 跳過上傳圖片
- 您是否打算將該產品進行商業銷售?:否
- 這是兒童產品還是以其他方式針對 13 歲以下的兒童?:否
創建產品后,我們將擁有應用程序 ID 和應用程序密碼。
我們將使用 alexamission-01 作為測試平臺,為此我們只需用您自己的方式更改 id 和 secret,請確保不需要引號。
[GadgetSettings]
amazonId = YOUR_GADGET_AMAZON_ID
alexaGadgetSecret = YOUR_GADGET_SECRET
[GadgetCapabilities]
Alexa.Gadget.StateListener = 1.0 - wakeword
我們可以像上一步一樣上傳代碼,完整的代碼解釋位于任務 01本身。
為了執行代碼,我們將做一些與alexa gadget不同的事情,執行這些代碼需要一些時間,有時我們會等待掛起而不知道原因。我們可以通過 shell 終端本身手動完成。
之后,我們可以像任何其他 linux 一樣執行我們的文件。
此時我們可以使用 GRIPP3R 本身激活 alexa 喚醒詞。
第 4 步:構建 Alexa 應用程序
這一步緊密總結了alexagadget的使命3和使命4 ,因為我們需要可以構建alexa app的基本功能。
我們需要在 alexa 控制臺下創建一個新技能,為了保持一致,我們將其命名為 mindstorms,就像任務一樣。
我們將通過 node js 使用自定義和 Alexa 托管的后端,這只是為了在您執行任務時保持一致性,并使編寫不同的程序更容易
我們可以從任務 4 上傳 JSON 文件并從那里構建它。只是不要發射任何大炮,因為 GRIPP3R 電機無法處理。獲取 json 復制并粘貼后,單擊構建模型繼續。
這給了我們足夠的能力來做以下事情,我們稍后會談到這些。
- 意圖名稱(MoveIntent、SetSpeedIntent、SetCommandIntent)
- 插槽名稱(方向、持續時間、速度、命令)
- 槽值(“前進”、“后退”、“1”、“2”、“100”)
在這些構建完成后,我們將把任務 4 的所有文件上傳到 Alexa 代碼屏幕中的 lambda 中。詳細代碼說明可以看這里。
之后,我們可以進入測試模式,為“開發”啟用技能測試
至于代碼,您可以上傳代碼庫,也可以按照任務 4 中的代碼立即進行測試。
#!/usr/bin/env python3
# Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# You may not use this file except in compliance with the terms and conditions
# set forth in the accompanying LICENSE.TXT file.
#
# THESE MATERIALS ARE PROVIDED ON AN "AS IS" BASIS. AMAZON SPECIFICALLY DISCLAIMS, WITH
# RESPECT TO THESE MATERIALS, ALL WARRANTIES, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
# THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
import os
import sys
import time
import logging
import json
import random
import threading
from enum import Enum
from agt import AlexaGadget
from ev3dev2.led import Leds
from ev3dev2.sound import Sound
from ev3dev2.motor import OUTPUT_A, OUTPUT_B, OUTPUT_C, MoveTank, SpeedPercent, MediumMotor
from ev3dev2.sensor.lego import InfraredSensor
# Set the logging level to INFO to see messages from AlexaGadget
logging.basicConfig(level=logging.INFO, stream=sys.stdout, format='%(message)s')
logging.getLogger().addHandler(logging.StreamHandler(sys.stderr))
logger = logging.getLogger(__name__)
class Direction(Enum):
"""
The list of directional commands and their variations.
These variations correspond to the skill slot values.
"""
FORWARD = ['forward', 'forwards', 'go forward']
BACKWARD = ['back', 'backward', 'backwards', 'go backward']
LEFT = ['left', 'go left']
RIGHT = ['right', 'go right']
STOP = ['stop', 'brake', 'halt']
class Command(Enum):
"""
The list of preset commands and their invocation variation.
These variations correspond to the skill slot values.
"""
MOVE_CIRCLE = ['circle', 'move around']
MOVE_SQUARE = ['square']
SENTRY = ['guard', 'guard mode', 'sentry', 'sentry mode']
PATROL = ['patrol', 'patrol mode']
FIRE_ONE = ['cannon', '1 shot', 'one shot']
FIRE_ALL = ['all shots', 'all shot']
class EventName(Enum):
"""
The list of custom event name sent from this gadget
"""
SENTRY = "Sentry"
PROXIMITY = "Proximity"
SPEECH = "Speech"
class MindstormsGadget(AlexaGadget):
"""
A Mindstorms gadget that can perform bi-directional interaction with an Alexa skill.
"""
def __init__(self):
"""
Performs Alexa Gadget initialization routines and ev3dev resource allocation.
"""
super().__init__()
# Robot state
self.sentry_mode = False
self.patrol_mode = False
# Connect two large motors on output ports B and C
self.drive = MoveTank(OUTPUT_B, OUTPUT_C)
self.weapon = MediumMotor(OUTPUT_A)
self.sound = Sound()
self.leds = Leds()
self.ir = InfraredSensor()
# Start threads
threading.Thread(target=self._patrol_thread, daemon=True).start()
threading.Thread(target=self._proximity_thread, daemon=True).start()
def on_connected(self, device_addr):
"""
Gadget connected to the paired Echo device.
:param device_addr: the address of the device we connected to
"""
self.leds.set_color("LEFT", "GREEN")
self.leds.set_color("RIGHT", "GREEN")
logger.info("{} connected to Echo device".format(self.friendly_name))
def on_disconnected(self, device_addr):
"""
Gadget disconnected from the paired Echo device.
:param device_addr: the address of the device we disconnected from
"""
self.leds.set_color("LEFT", "BLACK")
self.leds.set_color("RIGHT", "BLACK")
logger.info("{} disconnected from Echo device".format(self.friendly_name))
def on_custom_mindstorms_gadget_control(self, directive):
"""
Handles the Custom.Mindstorms.Gadget control directive.
:param directive: the custom directive with the matching namespace and name
"""
try:
payload = json.loads(directive.payload.decode("utf-8"))
print("Control payload: {}".format(payload), file=sys.stderr)
control_type = payload["type"]
if control_type == "move":
# Expected params: [direction, duration, speed]
self._move(payload["direction"], int(payload["duration"]), int(payload["speed"]))
if control_type == "command":
# Expected params: [command]
self._activate(payload["command"])
except KeyError:
print("Missing expected parameters: {}".format(directive), file=sys.stderr)
def _move(self, direction, duration: int, speed: int, is_blocking=False):
"""
Handles move commands from the directive.
Right and left movement can under or over turn depending on the surface type.
:param direction: the move direction
:param duration: the duration in seconds
:param speed: the speed percentage as an integer
:param is_blocking: if set, motor run until duration expired before accepting another command
"""
print("Move command: ({}, {}, {}, {})".format(direction, speed, duration, is_blocking), file=sys.stderr)
if direction in Direction.FORWARD.value:
self.drive.on_for_seconds(SpeedPercent(speed), SpeedPercent(speed), duration, block=is_blocking)
if direction in Direction.BACKWARD.value:
self.drive.on_for_seconds(SpeedPercent(-speed), SpeedPercent(-speed), duration, block=is_blocking)
if direction in (Direction.RIGHT.value + Direction.LEFT.value):
self._turn(direction, speed)
self.drive.on_for_seconds(SpeedPercent(speed), SpeedPercent(speed), duration, block=is_blocking)
if direction in Direction.STOP.value:
self.drive.off()
self.patrol_mode = False
def _activate(self, command, speed=50):
"""
Handles preset commands.
:param command: the preset command
:param speed: the speed if applicable
"""
print("Activate command: ({}, {})".format(command, speed), file=sys.stderr)
if command in Command.MOVE_CIRCLE.value:
self.drive.on_for_seconds(SpeedPercent(int(speed)), SpeedPercent(5), 12)
if command in Command.MOVE_SQUARE.value:
for i in range(4):
self._move("right", 2, speed, is_blocking=True)
if command in Command.PATROL.value:
# Set patrol mode to resume patrol thread processing
self.patrol_mode = True
if command in Command.SENTRY.value:
self.sentry_mode = True
self._send_event(EventName.SPEECH, {'speechOut': "Sentry mode activated"})
# Perform Shuffle posture
self.drive.on_for_seconds(SpeedPercent(80), SpeedPercent(-80), 0.2)
time.sleep(0.3)
self.drive.on_for_seconds(SpeedPercent(-40), SpeedPercent(40), 0.2)
self.leds.set_color("LEFT", "YELLOW", 1)
self.leds.set_color("RIGHT", "YELLOW", 1)
if command in Command.FIRE_ONE.value:
print("Fire one", file=sys.stderr)
self.weapon.on_for_rotations(SpeedPercent(100), 3)
self._send_event(EventName.SENTRY, {'fire': 1})
self.sentry_mode = False
print("Sent sentry event - 1 shot, alarm reset", file=sys.stderr)
self.leds.set_color("LEFT", "GREEN", 1)
self.leds.set_color("RIGHT", "GREEN", 1)
if command in Command.FIRE_ALL.value:
print("Fire all", file=sys.stderr)
self.weapon.on_for_rotations(SpeedPercent(100), 10)
self._send_event(EventName.SENTRY, {'fire': 3})
self.sentry_mode = False
print("sent sentry event - 3 shots, alarm reset", file=sys.stderr)
self.leds.set_color("LEFT", "GREEN", 1)
self.leds.set_color("RIGHT", "GREEN", 1)
def _turn(self, direction, speed):
"""
Turns based on the specified direction and speed.
Calibrated for hard smooth surface.
:param direction: the turn direction
:param speed: the turn speed
"""
if direction in Direction.LEFT.value:
self.drive.on_for_seconds(SpeedPercent(0), SpeedPercent(speed), 2)
if direction in Direction.RIGHT.value:
self.drive.on_for_seconds(SpeedPercent(speed), SpeedPercent(0), 2)
def _send_event(self, name: EventName, payload):
"""
Sends a custom event to trigger a sentry action.
:param name: the name of the custom event
:param payload: the sentry JSON payload
"""
self.send_custom_event('Custom.Mindstorms.Gadget', name.value, payload)
def _proximity_thread(self):
"""
Monitors the distance between the robot and an obstacle when sentry mode is activated.
If the minimum distance is breached, send a custom event to trigger action on
the Alexa skill.
"""
count = 0
while True:
while self.sentry_mode:
distance = self.ir.proximity
print("Proximity: {}".format(distance), file=sys.stderr)
count = count + 1 if distance < 10 else 0
if count > 3:
print("Proximity breached. Sending event to skill", file=sys.stderr)
self.leds.set_color("LEFT", "RED", 1)
self.leds.set_color("RIGHT", "RED", 1)
self._send_event(EventName.PROXIMITY, {'distance': distance})
self.sentry_mode = False
time.sleep(0.2)
time.sleep(1)
def _patrol_thread(self):
"""
Performs random movement when patrol mode is activated.
"""
while True:
while self.patrol_mode:
print("Patrol mode activated randomly picks a path", file=sys.stderr)
direction = random.choice(list(Direction))
duration = random.randint(1, 5)
speed = random.randint(1, 4) * 25
while direction == Direction.STOP:
direction = random.choice(list(Direction))
# direction: all except stop, duration: 1-5s, speed: 25, 50, 75, 100
self._move(direction.value[0], duration, speed)
time.sleep(duration)
time.sleep(1)
if __name__ == '__main__':
gadget = MindstormsGadget()
# Set LCD font and turn off blinking LEDs
os.system('setfont Lat7-Terminus12x6')
gadget.leds.set_color("LEFT", "BLACK")
gadget.leds.set_color("RIGHT", "BLACK")
# Startup sequence
gadget.sound.play_song((('C4', 'e'), ('D4', 'e'), ('E5', 'q')))
gadget.leds.set_color("LEFT", "GREEN")
gadget.leds.set_color("RIGHT", "GREEN")
# Gadget main entry point
gadget.main()
# Shutdown sequence
gadget.sound.play_song((('E5', 'e'), ('C4', 'e')))
gadget.leds.set_color("LEFT", "BLACK")
gadget.leds.set_color("RIGHT", "BLACK")
和ini文件
[GadgetSettings]
amazonId = amazonid
alexaGadgetSecret = secret
[GadgetCapabilities]
Custom.Mindstorms.Gadget = 1.0
這應該使我們能夠控制機器人。我們將通過與下面相同的 shell 運行。完成后,您應該能夠控制機器人。
第 5 步:設置 Gripper Bot Alexa 端
現在是時候編寫機器人邏輯了。為了完成這個項目,我們需要機器人做 3 件事,來,拿東西,拿東西,按照從最簡單到最難的順序。這轉化為 ComeIntent、TakeIntent、BringIntent
在這一步中,我們將更改整個項目,因此以前的任務現在不是很有用。我們可以使用下面的json文件。其中一個重要的變化是“invocationName”:“gripper bot” ,所以我們可以調用gripper bot來幫助我們在Alexa中
{
"interactionModel": {
"languageModel": {
"invocationName": "gripper bot",
"intents": [
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "HelloWorldIntent",
"slots": [],
"samples": [
"hello",
"how are you",
"say hi world",
"say hi",
"hi",
"say hello world",
"say hello"
]
},
{
"name": "ComeIntent",
"slots": [],
"samples": [
"Come",
"Come to me",
"Come here"
]
},
{
"name": "TakeIntent",
"slots": [
{
"name": "Item",
"type": "ItemType"
}
],
"samples": [
"Take this",
"Take it",
"Take this item",
"Take this {Item}",
"Take the {Item}"
]
},
{
"name": "BringIntent",
"slots": [
{
"name": "Item",
"type": "ItemType"
}
],
"samples": [
"Bring me the stuff",
"Bring me my item",
"Fetch my stuff",
"Bring me my {Item}"
]
},
{
"name": "AMAZON.NavigateHomeIntent",
"samples": []
}
],
"types": [
{
"name": "ItemType",
"values": [
{
"name": {
"value": "bottle"
}
},
{
"name": {
"value": "cane"
}
},
{
"name": {
"value": "medicine"
}
},
{
"name": {
"value": "cup"
}
}
]
}
]
}
}
}
至于lamdba 中的index.js ,我們基于任務 4 添加了額外的 3 個 Intent,這很重要,因為我們將這些意圖傳遞給了抓取機器人本身。
// Construct and send a custom directive to the connected gadget with data from
// the ComeIntent.
const ComeIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'ComeIntent';
},
handle: function (handlerInput) {
const attributesManager = handlerInput.attributesManager;
let endpointId = attributesManager.getSessionAttributes().endpointId || [];
let speed = "50";
// Construct the directive with the payload containing the move parameters
let directive = Util.build(endpointId, NAMESPACE, NAME_CONTROL,
{
type: 'come',
command: 'come',
speed: speed
});
let speechOutput = 'Gripper Bot is coming to you';
return handlerInput.responseBuilder
.speak(speechOutput + BG_MUSIC)
.addDirective(directive)
.getResponse();
}
};
// Construct and send a custom directive to the connected gadget with data from
// the BringIntent.
const BringIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'BringIntent';
},
handle: function (handlerInput) {
let command = Alexa.getSlotValue(handlerInput.requestEnvelope, 'Item');
if (command === "" || command === null)
command = "it to you";
else{
command = command + " to you"
}
const attributesManager = handlerInput.attributesManager;
let endpointId = attributesManager.getSessionAttributes().endpointId || [];
let speed = attributesManager.getSessionAttributes().speed || "50";
// Construct the directive with the payload containing the move parameters
let directive = Util.build(endpointId, NAMESPACE, NAME_CONTROL,
{
type: 'bring',
command: command,
speed: speed
});
let speechOutput = 'bringing ' + command;
return handlerInput.responseBuilder
.speak(speechOutput + BG_MUSIC)
.addDirective(directive)
.getResponse();
}
};
// Construct and send a custom directive to the connected gadget with data from
// the BringIntent.
const TakeIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'TakeIntent';
},
handle: function (handlerInput) {
let command = Alexa.getSlotValue(handlerInput.requestEnvelope, 'Item');
if (command === "" || command === null)
command = "the item";
const attributesManager = handlerInput.attributesManager;
let endpointId = attributesManager.getSessionAttributes().endpointId || [];
let speed = attributesManager.getSessionAttributes().speed || "50";
// Construct the directive with the payload containing the move parameters
let directive = Util.build(endpointId, NAMESPACE, NAME_CONTROL,
{
type: 'take',
command: command,
speed: speed
});
let speechOutput = 'taking ' + command;
return handlerInput.responseBuilder
.speak(speechOutput + BG_MUSIC)
.addDirective(directive)
.getResponse();
}
};
// The SkillBuilder acts as the entry point for your skill, routing all request and response
// payloads to the handlers above. Make sure any new handlers or interceptors you've
// defined are included below. The order matters - they're processed top to bottom.
exports.handler = Alexa.SkillBuilders.custom()
.addRequestHandlers(
LaunchRequestHandler,
ComeIntentHandler,
TakeIntentHandler,
BringIntentHandler,
EventsReceivedRequestHandler,
ExpiredRequestHandler,
Common.HelpIntentHandler,
Common.CancelAndStopIntentHandler,
Common.SessionEndedRequestHandler,
Common.IntentReflectorHandler, // make sure IntentReflectorHandler is last so it doesn't override your custom intent handlers
)
.addRequestInterceptors(Common.RequestInterceptor)
.addErrorHandlers(
Common.ErrorHandler,
)
.lambda();
完整代碼可以在代碼上傳端看到
第 6 步:編寫 GRIPP3R 輔助機器人邏輯
我們需要套件不附帶的陀螺儀傳感器(如果您有它,它包含在核心教育套件中)。我們可以在沒有它的情況下做到這一點,但是沒有它來計時 180 度轉彎是相當不準確的。
from ev3dev2.sensor.lego import GyroSensor
self.gyro = GyroSensor()
這里有 4 個主要的代碼審查,首先來。下面的代碼很簡單。
當 ComeIntent 讓 Robot 來找我們時,它會啟動 _come 向前移動。并且當紅外傳感器檢測到任何低于55的東西時,它會停止,當機器人停止時,它會打開把手,等待物品。
def on_custom_mindstorms_gadget_control(self, directive):
"""
Handles the Custom.Mindstorms.Gadget control directive.
:param directive: the custom directive with the matching namespace and name
"""
try:
payload = json.loads(directive.payload.decode("utf-8"))
print("Control payload: {}".format(payload), file=sys.stderr)
control_type = payload["type"]
if control_type == "move":
# Expected params: [direction, duration, speed]
self._move(payload["direction"], int(payload["duration"]), int(payload["speed"]))
elif control_type == "come":
self._come()
elif control_type == "take":
self._take()
elif control_type == "bring":
self._bring()
except KeyError:
print("Missing expected parameters: {}".format(directive), file=sys.stderr)
def _come(self, duration=10, speed=50):
self.leds.set_color("LEFT", "GREEN", 1)
self.leds.set_color("RIGHT", "GREEN", 1)
self.isComing = True
self._move(Direction.FORWARD.value[0], duration, speed)
def _proximity_thread(self):
"""
Monitors the distance between the robot and an obstacle when sentry mode is activated.
If the minimum distance is breached, send a custom event to trigger action on
the Alexa skill.
"""
if distance <= 55:
"""
When the bot is coming, it will stop and open up it's arm
"""
if self.isComing == True:
self.isComing = False
print("Proximity breached, stopping")
self._move(Direction.STOP.value[0], 0, 0,)
self.leds.set_color("LEFT", "RED", 1)
self.leds.set_color("RIGHT", "RED", 1)
while not self.touch.is_pressed:
self.grip.on_for_degrees(SpeedPercent(10), -90)
print("Lowered the grip")
對于接下來的 2 個部分,我們需要轉動,在紅外距離傳感器的同一線程下,我們還將檢測轉動,我們將電機移動得非常慢,以便我們可以檢測到準確的角度,每當它達到 180 度時,機器人就會停止,繼續執行下一個狀態。
self.gyro.reset()
self.isTurning = True
self.gyro.mode = 'GYRO-RATE'
self.gyro.mode = 'GYRO-ANG'
self.drive.on_for_seconds(SpeedPercent(4), SpeedPercent(-4), 40, block=False)
if self.isTurning == True:
print("angle: {}".format(angle), file=sys.stderr)
self.leds.set_color("LEFT", "YELLOW", 1)
self.leds.set_color("RIGHT", "YELLOW", 1)
if abs(angle) >= 179 or abs(angle) <= -181:
self.isTurning = False
self._move(Direction.STOP.value[0], 0, 0,)
self.gyro.reset()
self.gyro.mode = 'GYRO-RATE'
self.gyro.mode = 'GYRO-ANG'
self.leds.set_color("LEFT", "GREEN", 1)
self.leds.set_color("RIGHT", "GREEN", 1)
當 TakeIntent 從服務器被命中時,我們將命中 _take 函數。它將抓住物品,轉動 180 度,然后前往基地。當紅外傳感器擊中時,它會掉落物品,后退一秒鐘并轉回 180 度。
def on_custom_mindstorms_gadget_control(self, directive):
"""
Handles the Custom.Mindstorms.Gadget control directive.
:param directive: the custom directive with the matching namespace and name
"""
try:
payload = json.loads(directive.payload.decode("utf-8"))
print("Control payload: {}".format(payload), file=sys.stderr)
control_type = payload["type"]
if control_type == "move":
# Expected params: [direction, duration, speed]
self._move(payload["direction"], int(payload["duration"]), int(payload["speed"]))
elif control_type == "come":
self._come()
elif control_type == "take":
self._take()
def _take(self, duration=10, speed=50):
self.grip.on_for_rotations(SpeedPercent(100), 1)
self.leds.set_color("LEFT", "GREEN", 1)
self.leds.set_color("RIGHT", "GREEN", 1)
self.gyro.reset()
self.gyro.mode = 'GYRO-RATE'
self.gyro.mode = 'GYRO-ANG'
self.isTurning = True
self.drive.on_for_seconds(SpeedPercent(4), SpeedPercent(-4), 40)
self.isTaking = True
self.drive.on_for_seconds(SpeedPercent(50), SpeedPercent(50), duration)
elif self.isTaking ==True:
self.isTaking = False
print("Proximity breached, stopping")
self._move(Direction.STOP.value[0], 0, 0,)
self.leds.set_color("LEFT", "RED", 1)
self.leds.set_color("RIGHT", "RED", 1)
while not self.touch.is_pressed:
self.grip.on_for_degrees(SpeedPercent(10), -90)
print("Dropping Item")
self.drive.on_for_seconds(SpeedPercent(-50), SpeedPercent(-50), 1)
self.gyro.reset()
self.isTurning = True
self.gyro.mode = 'GYRO-RATE'
self.gyro.mode = 'GYRO-ANG'
self.drive.on_for_seconds(SpeedPercent(4), SpeedPercent(-4), 40, block=False)
self.leds.set_color("LEFT", "GREEN", 1)
self.leds.set_color("RIGHT", "GREEN", 1)
BringIntent 是最復雜的一個。一旦將控制權傳遞給機器人,我們首先調用_bring函數,它會轉180度,步行1秒并抓住物品,然后它會轉180度,來到我們身邊,一旦通過紅外傳感器檢測到我們,它就會下降物品和走回來的時間與它走到我們身邊的時間相同。
def on_custom_mindstorms_gadget_control(self, directive):
"""
Handles the Custom.Mindstorms.Gadget control directive.
:param directive: the custom directive with the matching namespace and name
"""
try:
payload = json.loads(directive.payload.decode("utf-8"))
print("Control payload: {}".format(payload), file=sys.stderr)
control_type = payload["type"]
if control_type == "move":
# Expected params: [direction, duration, speed]
self._move(payload["direction"], int(payload["duration"]), int(payload["speed"]))
elif control_type == "come":
self._come()
elif control_type == "take":
self._take()
elif control_type == "bring":
self._bring()
def _bring(self, duration=10):
self.isTurning = True
self.gyro.mode = 'GYRO-RATE'
self.gyro.mode = 'GYRO-ANG'
self.drive.on_for_seconds(SpeedPercent(4), SpeedPercent(-4), 40)
self.drive.on_for_seconds(SpeedPercent(50), SpeedPercent(50), 1)
self.grip.on_for_rotations(SpeedPercent(100), 1)
self.isTurning = True
self.gyro.mode = 'GYRO-RATE'
self.gyro.mode = 'GYRO-ANG'
self.drive.on_for_seconds(SpeedPercent(4), SpeedPercent(-4), 40)
self.isBringing = True
self.now = time.time()
self.drive.on_for_seconds(SpeedPercent(50), SpeedPercent(50), duration)
self.leds.set_color("LEFT", "GREEN", 1)
self.leds.set_color("RIGHT", "GREEN", 1)
def _proximity_thread(self):
if distance <= 55:
elif self.isBringing ==True:
self.isBringing = False
print("Proximity breached, stopping")
self._move(Direction.STOP.value[0], 0, 0)
self.later = time.time()
self.leds.set_color("LEFT", "RED", 1)
self.leds.set_color("RIGHT", "RED", 1)
while not self.touch.is_pressed:
self.grip.on_for_degrees(SpeedPercent(10), -90)
print("Dropping Item")
difference = int(self.later - self.now)
self.drive.on_for_seconds(SpeedPercent(-50), SpeedPercent(-50), difference)\
第 7 步:演示!
通過這 3 個功能,我們基本上可以讓機器人為我們存儲物品,并在我們需要時獲取物品。該機器人能夠存儲從藥瓶到奶瓶的任何東西。這些功能對行動不便的老年人特別有幫助。
我們在 300 美元以下構建了所有這些,您絕對可以按照指南在 20 小時內完成。這是一個開源項目,我們可以改進這些功能并在未來幫助老年人。
- 檢測機器人開源分享
- 基于Jetson NANO的助手機器人
- 坦克機器人開源分享
- 掃地機器人開源資料 43次下載
- 機器人守衛開源分享
- 伺服機器人開源分享
- 基于Python的AI助手機器人 1次下載
- 英雄機器人開源
- 機器人開源案例
- 3R平面藝術機器人開源分享
- Arduino機器人開源分享
- 帶有Arduino和Python的AI助手機器人
- 基于DSP和PC的農業機器人控制系統 17次下載
- 基于EtherCAT和TwinCAT3的協作機器人控制系統 14次下載
- 開架式通用水下機器人開源搭建手冊.pdf 11次下載
- 字節發布機器人領域首個開源視覺-語言操作大模型,激發開源VLMs更大潛能 360次閱讀
- 機器人技術中常用的路徑規劃算法的開源庫 843次閱讀
- 面對疫情 醫療機器人能幫上什么忙? 2126次閱讀
- dfrobotSparki機器人套裝簡介 2064次閱讀
- 醫用機器人的定義_醫用機器人發展 3122次閱讀
- 醫用機器人的功能_醫用機器人分類 2227次閱讀
- 協作機器人的起源_為什么需要協作機器人 8127次閱讀
- 盤點2018年機器人領域十大技術 3312次閱讀
- 如何區分機器人、協作機器人和移動機器人? 6828次閱讀
- 關于機器人傳感器的種類介紹 1.3w次閱讀
- 軟體機器人 前所未見的機器人 3692次閱讀
- 機器人的最佳編程語言是什么?機器人十大流行編程語言匯總 3.4w次閱讀
- 何為柔性機器人?如何讓機器人的身體柔若無骨? 1.1w次閱讀
- 手機如何連接小米掃地機器人_小米掃地機器人怎么連wifi 17.6w次閱讀
- 3種奇葩機器人的簡單介紹 5321次閱讀
下載排行
本周
- 1山景DSP芯片AP8248A2數據手冊
- 1.06 MB | 532次下載 | 免費
- 2RK3399完整板原理圖(支持平板,盒子VR)
- 3.28 MB | 339次下載 | 免費
- 3TC358743XBG評估板參考手冊
- 1.36 MB | 330次下載 | 免費
- 4DFM軟件使用教程
- 0.84 MB | 295次下載 | 免費
- 5元宇宙深度解析—未來的未來-風口還是泡沫
- 6.40 MB | 227次下載 | 免費
- 6迪文DGUS開發指南
- 31.67 MB | 194次下載 | 免費
- 7元宇宙底層硬件系列報告
- 13.42 MB | 182次下載 | 免費
- 8FP5207XR-G1中文應用手冊
- 1.09 MB | 178次下載 | 免費
本月
- 1OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費
- 2555集成電路應用800例(新編版)
- 0.00 MB | 33566次下載 | 免費
- 3接口電路圖大全
- 未知 | 30323次下載 | 免費
- 4開關電源設計實例指南
- 未知 | 21549次下載 | 免費
- 5電氣工程師手冊免費下載(新編第二版pdf電子書)
- 0.00 MB | 15349次下載 | 免費
- 6數字電路基礎pdf(下載)
- 未知 | 13750次下載 | 免費
- 7電子制作實例集錦 下載
- 未知 | 8113次下載 | 免費
- 8《LED驅動電路設計》 溫德爾著
- 0.00 MB | 6656次下載 | 免費
總榜
- 1matlab軟件下載入口
- 未知 | 935054次下載 | 免費
- 2protel99se軟件下載(可英文版轉中文版)
- 78.1 MB | 537798次下載 | 免費
- 3MATLAB 7.1 下載 (含軟件介紹)
- 未知 | 420027次下載 | 免費
- 4OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費
- 5Altium DXP2002下載入口
- 未知 | 233046次下載 | 免費
- 6電路仿真軟件multisim 10.0免費下載
- 340992 | 191187次下載 | 免費
- 7十天學會AVR單片機與C語言視頻教程 下載
- 158M | 183279次下載 | 免費
- 8proe5.0野火版下載(中文版免費下載)
- 未知 | 138040次下載 | 免費
評論
查看更多