toio は、センサーが付いた超小型のロボットプラットフォームとして手軽に利用することができます。
この記事では、iPhoneやiPadを使ってPCを使わずにプログラミングする方法を説明します。
まず、toioやPythonistaが手元にない方は次のものを用意しましょう。(合計約1万円)
今回のサンプルプログラムは、次のファイルで構成されています。
- toio.py 実際の処理を記述しているファイル
- toio.pyui UIの定義を記述しているファイル
.pyuiについては、Pythonista上でGUIベースで定義をすることができます。
プログラムの起動直後は、toioを検索している状態の画面になります。
その後、toioに接続できると次の画面になります。
この状態で、矢印を押すとその方向へ移動します。(厳密には前後のみ、右左は回転するだけ)
動作については、toio コア キューブ 通信仕様: モーターに書いてある書式にそって記述します。
プログラム中の
delegate.send_action('\x02\x01\x01\x32\x02\x01\x32\x0a')
などの部分を修正すれば様々な動きへ変更することができます。
toio コア キューブ 通信仕様では、モーター以外の使い方についても書かれていますので、こちらを参照し、次のサンプルプログラムを改造してみてください。
toio.py
import ui
import cb
import sound
import struct
TOIO_SERVICE_UUID = '10B20100-5B3B-4571-9508-CF3EFCD7BBAE'
TOIO_CHAR_UUID = '10B20102-5B3B-4571-9508-CF3EFCD7BBAE'
def button_tapped(sender):
'@type sender: ui.Button'
# Get the button's title for the following logic:
t = sender.name
if t == 'forwardButton':
delegate.send_action('\x02\x01\x01\x32\x02\x01\x32\x0a')
elif t == 'rightButton':
delegate.send_action('\x02\x01\x01\x32\x02\x02\x32\x0d')
elif t == 'leftButton':
delegate.send_action('\x02\x01\x02\x32\x02\x01\x32\x0d')
elif t == 'backButton':
delegate.send_action('\x02\x01\x02\x32\x02\x02\x32\x0a')
else:
print('error')
class MyCentralManagerDelegate (object):
def __init__(self):
self.peripheral = None
self.temp = 0
def did_discover_peripheral(self, p):
global text_state
# print('+++ Discovered peripheral: %s (%s)' % (p.name, p.uuid))
if p.name and 'toio Core Cube' in p.name and not self.peripheral:
# Keep a reference to the peripheral, so it doesn't get garbage-collected:
self.peripheral = p
cb.connect_peripheral(self.peripheral)
view['stateLabel'].text = '接続完了'
def did_connect_peripheral(self, p):
print('*** Connected: %s' % p.name)
print('Discovering services...')
p.discover_services()
def did_fail_to_connect_peripheral(self, p, error):
print('Failed to connect')
def did_disconnect_peripheral(self, p, error):
print('Disconnected, error: %s' % (error,))
self.peripheral = None
def did_discover_services(self, p, error):
for s in p.services:
if TOIO_SERVICE_UUID in s.uuid:
print('+++ toio found')
p.discover_characteristics(s)
def did_discover_characteristics(self, s, error):
if TOIO_SERVICE_UUID in s.uuid:
for c in s.characteristics:
if TOIO_CHAR_UUID in c.uuid:
self.data_characteristic = c
def did_write_value(self, c, error):
pass
def did_update_value(self, c, error):
pass
def send_action(self, data):
self.peripheral.write_characteristic_value(
self.data_characteristic, data, False)
view = ui.load_view()
view.present('sheet')
delegate = MyCentralManagerDelegate()
view['stateLabel'].text = '検索中'
cb.set_central_delegate(delegate)
cb.scan_for_peripherals()
# Keep the connection alive until the 'Stop' button is pressed:
try:
while True:
pass
except KeyboardInterrupt:
pass
# Disconnect everything:
cb.reset()
toio.pyui
[
{
"nodes" : [
{
"nodes" : [
],
"frame" : "{{91, 0}, {79, 93}}",
"class" : "Button",
"attributes" : {
"action" : "button_tapped",
"frame" : "{{90, 159}, {80, 32}}",
"title" : "↑",
"uuid" : "094421CA-AF11-4247-941A-26A72D24FCDE",
"class" : "Button",
"name" : "forwardButton",
"font_size" : 15
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{0, 106}, {84, 85}}",
"class" : "Button",
"attributes" : {
"action" : "button_tapped",
"frame" : "{{90, 159}, {80, 32}}",
"title" : "←",
"class" : "Button",
"uuid" : "094421CA-AF11-4247-941A-26A72D24FCDE",
"font_size" : 15,
"name" : "leftButton"
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{178, 106}, {84, 85}}",
"class" : "Button",
"attributes" : {
"action" : "button_tapped",
"frame" : "{{90, 159}, {80, 32}}",
"title" : "→",
"class" : "Button",
"uuid" : "094421CA-AF11-4247-941A-26A72D24FCDE",
"font_size" : 15,
"name" : "rightButton"
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{91, 204}, {79, 93}}",
"class" : "Button",
"attributes" : {
"action" : "button_tapped",
"frame" : "{{90, 159}, {80, 32}}",
"title" : "↓ ",
"class" : "Button",
"uuid" : "094421CA-AF11-4247-941A-26A72D24FCDE",
"font_size" : 15,
"name" : "backButton"
},
"selected" : true
},
{
"nodes" : [
],
"frame" : "{{91, 106}, {79, 85}}",
"class" : "Label",
"attributes" : {
"name" : "stateLabel",
"frame" : "{{56, 134}, {150, 32}}",
"uuid" : "A42275C6-F449-4054-BF40-2A32BD61053B",
"class" : "Label",
"alignment" : "center",
"text" : "",
"font_size" : 18,
"font_name" : "<System>"
},
"selected" : false
}
],
"frame" : "{{0, 0}, {262, 299}}",
"class" : "View",
"attributes" : {
"background_color" : "RGBA(1.000000,1.000000,1.000000,1.000000)",
"enabled" : true,
"tint_color" : "RGBA(0.000000,0.478000,1.000000,1.000000)",
"name" : "",
"border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)",
"flex" : ""
},
"selected" : false
}
]