• カテゴリ 雑記 の最新配信
  • RSS
  • RDF
  • ATOM

ブログ - 雑記カテゴリのエントリ

PMXネタつながりで

カテゴリ : 
雑記
2024-4-25 9:50
事のついでで恐縮だが、キャリアボードの評価をお願いしている方からKO B3Mがマトモに動かないという指摘があったので、そのついでに作っておいた。10年前にこねくり回すのを諦めてから重い腰を上げて弄ったが、結局のところB3Mの癖は拭い切れないまま。

こちらも事のついでだが、少し毛色の違うサーボを引っ張り出して触っておいたレポートを。

外観が何かに酷似しているのは気のせいとして、サーボモータとして最低限の制御を行うついでに、テキストベースのプロトコルを被せているところが毛色の違いかと。ようするに俺サーボ。
適当なシリアルターミナル上でポチポチキーボードを打てばとりあえず動くが、プログラムからテキストで通信させるとなると却って面倒。こちらも例に漏れずPythonで記述するためのクラスが用意されているが、シリアル通信部分を隠蔽するだけで実質何もしておらず、結局正規表現任せ。

これを2個使い相互リンクをやらせてみた(単に互いの位置偏差を電流指令しているだけだが)。実機を持つ方はたかが知れているのでコードを晒すまでもないが、2軸への電流制御モード設定・ゲイン設定・電流指令・現在値取得が1パケットで済み、要点のみであれば実質数行で済む(PeriodicTimerは周期タイマクラス)。
#!/usr/bin/python3
#
# Link two servos with virtual wires

import os, platform, psutil, time, kbhit, serial, numpy as np
from PeriodicTimer import PeriodicTimer
from jp200class import packet

intervalms = 20

try:
pr = psutil.Process(os.getpid())
if platform.system() == 'Windows':
pr.nice(psutil.HIGH_PRIORITY_CLASS)
else:
pr.nice(-10)
except:
print('info:run with sudo')

# present value
present_dt = [('ang',float),('cur',float),('velo',float)]
present = np.empty(2, dtype = present_dt)
# calculated current command value
tcur = [0.0] * 2

#--------------------------------
# Periodically executed functioin
#--------------------------------
def cycfunc(*p):
sv = p[0]
acks = []
# deviation from each other's position
tcur = (
np.clip((present[1]['ang'] - present[0]['ang']) * 0.15, -1000.0, 1000.0),
np.clip((present[0]['ang'] - present[1]['ang']) * 0.15, -1000.0, 1000.0)
)
# send current command and current position acquisition to JP200
sv.request(
'#0EX=4SG2=9000;5500;10TC=%dTP=1000CACVCC'
'#1EX=4SG2=9000;5500;10TC=%dTP=1000CACVCC'
%(tcur[0], tcur[1]), acks
)
# analyze response
if acks:
for ack in acks:
m = sv.p2.findall(ack)
id = -1
for n in m:
try:
if n[0] == '#' and int(n[1]) >= 0: id = int(n[1])
elif n[0] == 'CA' and id >= 0: present[id]['ang'] = float(n[1])
elif n[0] == 'CC' and id >= 0: present[id]['cur'] = float(n[1])
elif n[0] == 'CV' and id >= 0: present[id]['velo'] = float(n[1])
except:
pass
if id >= 0: print('[%d] %4d %8d %5d %5d '%(id, tcur[id], present[id]['ang'], present[id]['velo'], present[id]['cur']), end = '')
print(end = '\r')

# instantiate kbhit
kb = kbhit.KBHit()
# open UART
ser = serial.Serial('/dev/ttyAMA0', 2000000)
print(ser.name)
# instantiate JP200
sv = packet(ser, 0.02)
# instantiate periodic timer & start
tm = PeriodicTimer(intervalms / 1000, cycfunc, [sv])

acks = []
k = ''
while k != 'q':
# waiting for key input
try:
k = kb.getch()
except UnicodeDecodeError:
pass
print(k, end = '\n', flush = True)

# move to origin position
if k == 'h':
tm.stop()
sv.request('#0EX=1TA=18000TP=1000#1EX=1TA=18000TP=1000', acks)
# stop timer
elif k == 's':
tm.stop()
tm.start()
# start timer
elif k == 'e':
tm.stop()
sv.request('#0EX=0#1EX=0', acks)
elif k == 'c':
tm.stop()
sv.request('#0EX=8TP=1000#1EX=8TP=1000', acks)
time.sleep(5)
sv.request('#0EX=8TP=-1000#1EX=8TP=-1000', acks)
time.sleep(5)
sv.request('#0EX=0#1EX=0', acks)
else:
print('XXXXXXXXX')
tm.stop()

sv.request('#0EX=0#1EX=0', acks, True)
ser.close()
kb.set_normal_term()
del sv, ser, kb

os._exit(0)
今回はRZ/V2LのDRP-AIを評価したベンチで使ったサーボをZero 2 Wでも試してみたに過ぎないが、こんな具合に使える(長いだけで大して面白くないので再生するまでもなく)。

事のついでと書いている大本の理由は、ここ最近XL330/XC330が軒並み通信できないベンチに遭遇して痛い目にあっており、動かすチャンスがあるときは一通り試しておかないと気が気でないものだから(XC330/XL330はボーレートの許容誤差が狭い)。

技術

KONDO PMX試食3

カテゴリ : 
雑記
2024-4-18 11:20
前回に引き続き小出し第3弾。

その前に、今までPMXのボーレートを3Mbpsとしていたが、バックグラウンドで動かしているアプリケーションによって受信データの欠損やズレが散見されていた。そのために態々リトライする関数を用意した訳だが。
原因を追求すべく色々試した結果、Zero 2の都合で時折受信データを取りこぼしていると考えられ、最終的にはボーレートにも依存するところまで判明した。OSが過負荷状態であっても、今のところ1.5Mbps以下であれば受信データを取りこぼさないようだ。

それでは本題に。
前回の漫画にどうしてXC330-T181-Tがつながっていたかの答えでもあるが、常々やってみたかったのが、異なる異メーカのサーボを同時に使うという少々危険なネタ。
これをやってみようと思ったのは、DXLに用意されているV1/V2の通信プロトコルを混在させている実例があったのと、PMXの通信プロトコルがB3MやKRSシリーズのプロトコルに比べ格段に堅牢になっていたからでもある。また単一メーカに依存して無い物ねだりする事を無くす事も狙い。
ちなみにB3MやKRSでは深く考えるまでもなく絶対的に無理、というか危険極まりないのでやってはならない。またDXLもV1とV2を混在させるとV1側の挙動がおかしくなるのは既知なので、実質的に無理。プロトコルの混在を実現するには、各サーボが自身には無関係なパケットを即時破棄する事と、自身に関係のあるパケットを取りこぼさないというそこそこ厳しい条件が求められる。それらは当然こちらでどうにかできる話ではないので、完全に自己責任のネタである。

では徐にやってみる。
PMXはID=0でボーレートを1Mbps、DXLはID=1でボーレートを1Mbpsとした。そもそもプロトコルが異なるのでお互いにIDが同じであっても構わないだろう。ライブラリは前回同様にpyPMX.pypyDXL.pyを使用。以下は1つのコードになっているか、PMXとDXLを各々個別のスレッドで処理させ、互いの存在は全く意識していない。オープンしたポートのインスタンスとLockを両スレッド共通に使用している。いずれも正弦波を元に位置決め制御を行いつつ、現在位置を取得してモニタ用の変数に書き込んでいる。ループ中には適当な時間のsleepを入れておいた方が良いだろう。
#!/usr/bin/python3
from pyPMX import *
from pyDXL import *
import math, kbhit, time, serial, threading

# Communication task with PMX
def func1(arg):
id = 0
# Class instantiation
pmx = PMXProtocol(arg[0], lock = arg[1])
# Setting initial conditions
pmx.MemREAD(id, 400, 6) # Clear error flag
pmx.MotorWRITE(id, 2, ()) # Torque free
pmx.MemWRITE8(id, 501, (1, 0b11111)) # Control mode (All)
pmx.MotorWRITE(id, 1, ()) # Torque enable
while arg[2]:
ang = int(math.sin(time.time()) * 9000.0)
r = pmx.MotorWRITE(id, 0, (ang,)) # Angle command
if r != None:
arg[3] = r[1][0]
time.sleep(0.001)
pmx.MotorWRITE(id, 2, ()) # Torque free
del pmx

# Communication task with DXL
def func2(arg):
id = 1
cnt = 0
led = 0
# Class instantiation
dx2 = DXLProtocolV2(arg[0], lock = arg[1])
# Setting initial conditions
dx2.Write8(id, 64, 1) # Torque enable
while arg[2]:
ang = int(math.sin(time.time()) * 1024.0) + 2047
dx2.Write32(id, 116, ang) # Angle command
r = dx2.Read32(id, 132, signed = True) # Read feedback values
if r != None:
arg[4] = r
cnt += 1
if cnt % 10 == 0:
led ^= 1
dx2.Write8(id, 65, led) # Update LED status
time.sleep(0.001)
dx2.Write8(id, 65, 0) # LED off
dx2.Write8(id, 64, 0) # Torque free
del dx2

kb = kbhit.KBHit()
# Open serial port
com = serial.Serial('/dev/ttyAMA0', 1000000, timeout=0.005)
lock = threading.Lock()
act = True
v1 = 0
v2 = 0
SharedVar = [com, lock, act, v1, v2]

# Start thread
th1 = threading.Thread(target = func1, args = [SharedVar])
th2 = threading.Thread(target = func2, args = [SharedVar])
th1.start()
th2.start()

# Loop until keyboard input
while True:
if kb.kbhit():
break
print(f' pmx:{SharedVar[3]:6d}, dxl:{SharedVar[4]:6d}', end = '\r')
time.sleep(0.05)

# End
SharedVar[2] = False
th1.join()
th2.join()

del kb, lock, com, th1, th2
print()
結果、いずれのサーボもスムーズに動くし、更に長時間運転してみても各関数はエラーを吐いていない。
色々虐め始めるとボロも出て来るだろうが、サーボそのものが不可解な挙動をしない限り、もしかしたら新たな使い道が見い出せるかも知れない。

キャリアボードに装備した機能の検証を含んだ操作している様子を動画にしておいた。

以上で久々に新鮮な気持ちで遊興したレポートを終える。

技術

KONDO PMX試食2

カテゴリ : 
雑記
2024-4-16 14:20
前回に引き続きPMX。

各装置の接続は最終的にこのような構成に。
キャリアボードに供給する電源が内蔵のスイッチ回路を介してEHコネクタからサーボへ供給される。
Raspberry Pi Zero 2 Wの操作はモニタとキーボードを直接接続して行うも良し、USB経由のRNDISでリモートログインしても良し、WiFi経由でリモートログインしても良し。
これでハードウェアの準備は完了。

ではようやくソフトウェアに。
Raspberry Pi Zero 2 WをホストとしたのでLinuxが前提、Zeroは極めてメモリが少ないのでCLIを基本とした。今回はモータが動きさえすれば良いので、プログラムのデバッグはキャラクタベースで十分と判断。
キャリアボードはRaspberry Piの機能を利用するので、本家のドキュメントDXHATの使用方法を元に設定。念のためcmdline.txtからconsoleの記述が消えているのを確認しておこう。
キャリアボードのRS-485 I/FはZeroの「/dev/ttyAMA0」に割り当てられる。
この辺は先人の知恵を借りれば良し。

次にPythonによるPMXとの通信だが、既にDXL用Pythonライブラリが公開されているのでその構成を真似ね、PMXのプロトコルで規定されているコマンドに応じた関数を用意し、こちらでpyPMX.pyとして公開。あると便利な検索・ID変更・ボーレート変更の各スクリプトも事のついでに作成。これにてオンラインマニュアル片手にポチポチと弄る準備が完了。
一応ライブラリの末尾にテストコードを仕込んでおいたが、PMXに位置決め制御を行わせるだけであれば、以下のように動作モードを設定しTorqueONした後にMotorWRITEで角度を指令するだけ。
#!/usr/bin/python3
import time
from pyPMX import PMXProtocol

ID = 0
BAUD = 3000000
# Create pmx instance
pmx = PMXProtocol('/dev/ttyAMA0', BAUD)

pmx.MemREAD(ID, 400, 6) # Error clear
pmx.MotorWRITE(ID, pmx.MOTW_OPT_FREE, ()) # Torque off
pmx.MemWRITE8(ID, 501, 1) # bit 0:pos,1:speed,2:cur,3:torq,4:pwm,5:time
pmx.MotorWRITE(ID, pmx.MOTW_OPT_TORQUEON, ()) # Torque on

for ang in (0, 4500, 9000, 4500, 0, -4500, -9000, -4500, 0):
pmx.MotorWRITE(ID, pmx.MOTW_OPT_NONE, (ang,)) # Command angle
time.sleep(0.5)
pmx.MotorWRITE(ID, pmx.MOTW_OPT_FREE, ()) # Torque off
実はこの程度の処理にもかかわらず、想定した動作を行ってくれない事が散見された。各関数の成否を確認しないまま次の処理に遷移させているため、初期設定の所で何かしら失敗したまま角度の指令がなされている時に動かなかった様だ。
それがキャリアボードの問題なのか通信方法の問題なのかの切り分けはしていないが、関数の返り値を確認してリトライする等の処理を加えれば、とりあえずお茶は濁せそうだ。

それらを意識した上で複数IDを一括で処置する関数を作成、少しだけコンソール上での操作をしやすくするためにkbhitを導入、最終的に2軸を対象にしたプログラムを作ってみた。
#!/usr/bin/python3

_retrynum = 3
# mode set & torque enable
def _setmode(pmx, id, m):
for i in range(_retrynum):
if pmx.MemWRITE8(id, 500, pmx.MOTW_OPT_FREE):
if m != 0:
# 1:pos,2:speed,4:cur,8:torq,16:pwm,32:time
if pmx.MemWRITE8(id, 501, m):
if pmx.MemWRITE8(id, 502, 0b11111):
if pmx.MemWRITE8(id, 503, 5):
if pmx.MemWRITE8(id, 500, pmx.MOTW_OPT_TORQUEON):
return True
else:
return True
return False

def SetMode(pmx, ids, m):
if isinstance(ids, list) or isinstance(ids, tuple):
r = 0
for i, id in enumerate(ids):
if isinstance(m, list) or isinstance(m, tuple):
r += 1 if _setmode(pmx, id, m[i]) else 0
else:
r += 1 if _setmode(pmx, id, m) else 0
return True if r == len(ids) else False
else:
return _setmode(pmx, ids, m)

# set angle
def _setangle(pmx, id, ang, t):
for i in range(_retrynum):
r = pmx.MotorWRITE(id, pmx.MOTW_OPT_NONE, (int(ang * 100), t))
if r != None:
if len(r) > 0:
return r[1]
return ()

def SetAngle(pmx, ids, angs, t):
if isinstance(ids, list) or isinstance(ids, tuple):
r = ()
for i, id in enumerate(ids):
if isinstance(angs, list) or isinstance(angs, tuple):
r += _setangle(pmx, id, angs[i], t),
else:
r += _setangle(pmx, id, angs, t),
return r
else:
return _setangle(pmx, ids, angs, t)

# set velocity
def _setvelocity(pmx, id, velo):
for i in range(_retrynum):
r = pmx.MotorWRITE(id, pmx.MOTW_OPT_NONE, (int(velo),))
if r != None:
if len(r) > 0:
return r[1]
return ()

def SetVelocity(pmx, ids, velos):
if isinstance(ids, list) or isinstance(ids, tuple):
r = ()
for i, id in enumerate(ids):
if isinstance(velos, list) or isinstance(velos, tuple):
r += _setvelocity(pmx, id, velos[i]),
else:
r += _setvelocity(pmx, id, velos),
return r
else:
return _setvelo(pmx, ids, velos)

def _getpresent(pmx, id):
for i in range(_retrynum):
r = pmx.MemREAD16(id, 300, 5, signed = True)
if r != None:
return r
return ()

def GetPresent(pmx, ids):
if isinstance(ids, list) or isinstance(ids, tuple):
r = ()
for i, id in enumerate(ids):
r += _getpresent(pmx, id),
return r
else:
return _getpresent(pmx, ids)

if __name__ == "__main__":
import os, sys, time, kbhit
from pyPMX import PMXProtocol

kb = kbhit.KBHit()
pmx = PMXProtocol('/dev/ttyAMA0', 3000000, 0.005)

ID1 = 0
ID2 = 1

# Position Control
print('Position Control')
print(f'{ID1}:angle velo cur torque pwm {ID2}:angle velo cur torque pwm')
if SetMode(pmx, (ID1, ID2), 1|32):
while not kb.kbhit():
t = 1000
for ang in (0, 45, 90, 45, 0, -45, -90, -45):
if kb.kbhit(): break
SetAngle(pmx, (ID1, ID2), (ang, ang * 2), t)
s = time.time() + t / 1000.0
while s > time.time():
if kb.kbhit(): break
r = GetPresent(pmx, (ID1, ID2))
for r in r:
print(('{:6d} '*len(r)).format(*r), end='')
print(end='\r')
SetMode(pmx, (ID1, ID2), 0)
kb.getch()

# Velocity Control
print('\nVelocity Control')
print(f'{ID1}:angle velo cur torque pwm {ID2}:angle velo cur torque pwm')
if SetMode(pmx, (ID1, ID2), 2):
while not kb.kbhit():
t = 3000
for velo in (0, 500, 1000, 1500, 1000, 500, 0, -500, -1000, -1500, -1000, -500):
if kb.kbhit(): break
SetVelocity(pmx, (ID1, ID2), (velo*1, velo*1.5))
s = time.time() + t / 1000.0
while s > time.time():
if kb.kbhit(): break
r = GetPresent(pmx, (ID1, ID2))
for r in r:
print(('{:6d} '*len(r)).format(*r), end='')
print(end='\r')
SetMode(pmx, (ID1, ID2), 0)

del kb, pmx
適当な指令値を元に位置決め制御と速度制御を行い、コンソール上で何か入力すると処理を推移する。制御中は読み出した現在値をバラバラとコンソールに吐き出し続ける。
紹介したコードはいらぬものも含んでいるので少々長くなっているが、SetModeを行って成功したらSetAngleやSetVelocityを行っているだけの事である。

Zeroを一通り操作している様子をラズパイカメラで自撮りしておいた。

ちなみに先の関数エラーはRS-485トランシーバの電気的な問題だったようで、真面目にターミネータの他にプルアップとプルダウン抵抗を装備して事なきを得た。

技術

KONDO PMX試食1

カテゴリ : 
雑記
2024-4-13 10:10
リリースから多少時間が経過した頃合いを見計らって、KONDO PMXシリーズに触れてみた。
今回は具体的に何かしらのカタチをなすものではなく、試作機や通信方式、Pythonといったところの評価を兼ねての事だが。
改めてPMXがどういった素性を持っているかを紹介するまでもないが、今回評価するにあたり必要な点を挙げておくと、
  • RS-485 I/F装備
  • 専用プロトコルを装備
  • 1つのI/Fのみで複数台を制御可能
  • 3Mbpsまでの通信速度に対応
  • 物理値を元にするのでモデルによる差異を意識することは無い
といったところで、Dynamixelで謳っている事と大きな差異はないが、指令やフィードバックが物理値という所が琴線に触れる。電気的には既存のI/Fを流用することもできるだろうし、プログラムとしての概念も自分の認識と大きく乖離するものでもなさそうだ。

PMXのコネクタは手持ちのI/Fとは何ら互換性が無いので、EHコネクタへ変換するだけのケーブルを用意。

これでPMX絡みの準備は終了。

Raspberry Pi Zero用に試作したキャリアボードの評価も兼ねているので、XC330-T181-TがつながるようにRS-485からTTLに変換するケーブルを準備。

最後にキャリアボード。DXHATPicoSHIELDのあいのこのようなもの。

事のついでにテスト中の短絡事故を防ぐ目的で、Raspberry Pi Zero 2 Wとキャリアボード全体を覆うエンクロージャを3Dプリンタで出力。

なんだかminiPCの様相を呈している。

今回はここまで。


技術

Pico

カテゴリ : 
雑記
2023-2-20 13:20
あまり目新しい事ができていないので、合間を見つけて手持ちのRaspberry Pi Pico用にこんなものをあつらえてみました。


板のサイズをPicoと同じにした都合、RS-485しか装備できず。余ったスペースにはオーディオアンプとレギュレータしか載ってません。
ひとまずXL430-W250とつなぐためにI/F変換をかませました。
試したところDXSHIELD用のライブラリは無改造で使えました。残念なのはボーレートが3Mbpsまでしか設定できない事と、USBとRS-485間のブリッジをこさえた際に気付いたのがPC側のアプリがハードフローを活性化していないとダメといったところでしょうか。

技術
ROSロボットプログラミングバイブルに続き、新刊のお知らせです。


Arduinoを使った電子工作や各社のサーボモータの最新情報を網羅したムックが出版されます。以前出版された二足歩行ロボット関連の書籍は現在の状況と合わなくなって来ている事もありますので、ロボット向けサーボモータを初めて使ってみようとお考えの方にはこちらをお勧めします。


Ohmsha
ROBO-ONEにチャレンジ! 二足歩行ロボット自作ガイド


本書は、二足歩行ロボット格闘技大会「ROBO-ONE」に参加できるロボットを製作する方法を解説したものです。
基本的なロボットの構成から、サーボなど使用する部品の概要、歩行などのプログラムの作成までを解説しています。サーボの制御はArduinoを使用し、最低限歩行がきちんとできるロボットを製作します。
後半では、「ROBO-ONE」の常連参加者による、ロボット製作のノウハウの紹介が中心となります。ロボット製作のコンセプトの考え方や、格闘技の技やダンスなどの動き(モーション)をプログラムする際のコツ、ハードウェア製作のコツなど、初心者がステップアップできるだけでなく、すでに製作の経験がある方でも役に立つ内容となっています。
ROSに興味があってもTurtleBotと直接的に関連する書籍が無いとお嘆きの貴兄。こんな書籍が発売されますので、ご参考にされてはいかがでしょう。


Ohmsha
ROSロボットプログラミングバイブル


本書は,ロボット用のミドルウェアであるROS(Robot Operating System)についての,ロボット分野の研究者や技術者を対象とした解説書です.ROSの構成や導入の方法,コマンドやツール等の紹介といった基本的な内容から,コミュニケーションロボットや移動ロボット,ロボットアームといった具体的なロボットのアプリケーションを作成する方法を解説しています.
ROSについて網羅した内容となるため,ROSを使った開発を行いたい方が必ず手元に置き,開発の際に活用されるような内容です.

ToFセンサとUSB-3WAY後継

カテゴリ : 
雑記
2017-7-31 17:10
興味を持って頂いた方には昨年より評価を行って頂いているToF(Time of Flight )センサですが、ワンメイクで終わらせずに採番し製品化する事を検討しています。
何種類かのセンサを試した上で、最終的にST社のLV53L0Xを装備し、例の如くDynamixelと同等のTTLないしRS-485 I/Fを介してアクセスする仕様としました。センサとI/F間の仲介役としてDXMIOと同様にNXP LPC824を搭載し、センサの情報を咀嚼してI/Fに流すといった役割を担います。
また、PSDセンサなどからの置き換えを意識し、アナログ電圧出力とデジタル出力を備えます。

製品化前ですが、評価時のドキュメントを最終版を意識して記載内容が更新されていますので、興味のある方はこちらをご覧下さい。

他に、プロトコルV2.0に対応したDynamixelシリーズが増えてきましたが、USB-3WAYやDXHUBは3Mbpsを超えるボーレートに対応していません。PCにおいて4Mbpsや4.5Mbpsで通信できれば、それだけで時間を有意義に利用できる事から、対応を望む声が少なからずありました。
単純にUSBシリアル変換ICをFT232Hに変更するだけで高いボーレートに対応しますが、それだけでは芸が無いので、USB-3WAYの後継のみ仕様を確定しました。
・D-SUBコネクタからの変換が既にレガシーなのでJSTのコネクタを装備
・Dongleシリーズでは中途半端に絶縁機能が入っていのでバスパワーのみで動作
・TTLとRS-485両I/Fに対応し、最大12Mbpsをサポート(FT232Hの仕様上限)


実機はこんな感じです(左:ToFセンサ、右:USBシリアル変換)。


製品化されたあかつきにはぜひご利用ください。

技術
今回は最終で、「Palmi ちょっとCommander」を紹介します。



「Palmiにちょっと何かをやらせてみよう」というアプリケーションだそうです。

画面を一瞬見た時に、「ん? もしかしてむずかしい?」と思うかもしれませんが、
いえいえ、むずかしいことはなく、Palmiにやって欲しい動作を選んで組合わせていくだけなんです。

どこをどう設定したらよいのか、まず迷うと思うので、最初にここを覗いておくとよいですよ。




「ちょっとコマンダー」でPalmiに設定した動作を、Palmi Fwapparの「やくそくごと」で確認できます。



それでは試しに、TVコマーシャルの「たけし、バカヤロー」をPalmiにやってもらいましょう! 

ちょっとコマンダーには、CMモーションが用意されているんですよぉ。
では、順番に設定してみますね。

「ToDoのキッカケを設定する」の文字をクリックすると別画面が表示されるので、“いつ?”は“顔を見たら”にして、 “誰の?”は“誰でも”を選択してみました。



次に、下記のように設定します。※1.2.3は順不同でOK。
1.「動き」のリスト→“話す(モーション付き)”を選択。
2.画面右下の「どのモーションをしますか?」→“CMモーション”をクリックして選択。
3.「何を話しますか?」→“たけし、バカヤロー”の言葉を入力。
4.「ToDoのプレビュー」ボタンを押す→Palmiが“たけし、バカヤロー”を動作する。

では、この動作に名前を付けて保存をすることに。
1.画面左上の「ToDoの名前を入力してください」をクリック→“たけし、バカヤロー”を入力。
2.画面下の「ToDoの保存」ボタンを押して完了!



Palmi Fwapparの「やくそくごと」に、しっかりと登録されています。



そしてこの後、Palmiに実証してもらおうと私の顔をみてもらったのですが、
残念ながら、“たけし、バカヤロー”のモーションをしてくれませんでした・・・・。
何でだろうなぁ・・・・

では、“誰でも顔をみたら”ではなく、時間で設定しなおしてみたら、
設定した時間に、Palmiは、“たけし、バカヤロー”をやってくれました!

本当は、時間ではなくて、“誰でも顔をみたら”で動作してほしいなぁ・・・・。

Palmiがやってきた
みっちゃん

熱い暑いぃ~

カテゴリ : 
雑記 » palmi
2015-11-5 19:10
試作中のLWIR Camの評価ついでに、「あついあつい」言ってた輩を観察。

背中あたりがなかなかホット。
どちらかと言えば末端冷え性。

首筋には襟巻き禁物ですね。クリスマスデコレーションの際は気をつけないと

Palmiがやってきた
技術