This page is Work in Progress
AIML supports OOB tags in the response from ProgramAB.
There is not a strict definition of what OOB tags are. For more info take a look at
https://code.google.com/p/aiml-en-us-pandorabots-callmom/wiki/CallMomOO…
OOB tags are usually something like <search>foo</search>
I'm adding support in ProgramAB to support an OOB tag of <mrl>...</mrl>
The XML syntax for this is
<mrl>
<service>python</service>
<method>exec</method>
<param>print "hello world"</param>
</mrl>
In the program AB AIML response template you could put something like the following
Create a new chat bot named "lloyd"
Create the file example.aiml and put it in the directory ProgramAB/bots/lloyd
Example AIML File:
[[home/kwatters/lloyd/aiml/lloyd.aiml]]
[[home/kwatters/lloyd/aiml/bootup.aiml]]
The following python code is an example of how to use this
[[home/kwatters/Lloyd.InMoov.ProgramAB.py]]
working example of OOB AIML tags and MRL.
Thanks for that Kwatters !
Thanks for that Kwatters !
Test Driver script: from
Test Driver script:
Some tests with AIML
Looks fine so far. Elias in controllable thru programAB/Superbot.
The shoulder issue is already solved.
Daisy Daisy
lookin' good... I really like the conditional responses you have there. bummer to hear the date tag wasn't working properly for you... I thought the "jformat" tag should have done it for you.
How to use programAB to run Inmoov
BIG THANKS TO KWATTERS AND MAVO!!!
1. Put these 2 aiml.files (startup.aiml and randommove.aiml) into your aiml folder (e.g. C:\mrl\ProgramAB\bots\alice2\aiml). Copy and paste it to your Notepad and safe it as named. Safe your aimlif folder somewhere else (just in case you need it) and make a new one (empty). One file is to start up Inmoov and the other one is a simple move sample. Please check your mapping/max/mins before use!!! Don't forget to change your botname (if you use alice just replace yourbotname with alice2). You can add the randommove to any existing aiml.file (or any def you like to add to any other aiml file) e.g.:
Original:
<category><pattern>HI</pattern>
<template><random>
<li>Hi nice to see you!</li>
<li>Hi it's great to see you!</li>
<li>Hi how are you?</li>
<li>Hi! I can really feel your smile today.</li>
<li>Hi! It's delightful to see you.</li>
</random></template>
</category>
Changed:
<category><pattern>HI</pattern>
<template><srai>RANDOMMOVE</srai><random>
<li>Hi nice to see you!</li>
<li>Hi it's great to see you!</li>
<li>Hi how are you?</li>
<li>Hi! I can really feel your smile today.</li>
<li>Hi! It's delightful to see you.</li>
</random></template>
</category>
The aiml-files:
startup.aiml
<?xml version="1.0" encoding="UTF-8"?>
<aiml>
<category><pattern>POWER UP YOURBOTNAME</pattern> #####change to your botname!
<template>Powering up
<oob>
<mrl>
<service>python</service>
<method>exec</method>
<param>
leftPort = "COM4" ######### PORTS!!!!!!!!!!!!!!
rightPort = "COM5" ######### PORTS!!!!!!!!!!!!!!
i01 = Runtime.createAndStart("i01", "InMoov")
i01 = Runtime.create("i01","InMoovHand")
i01.rightHand = Runtime.create("i01.rightHand","InMoovHand")
i01.rightHand.thumb.setRest(0)
i01.rightHand.index.setRest(30)
i01.rightHand.majeure.setRest(40)
i01.rightHand.ringFinger.setRest(60)
i01.rightHand.pinky.setRest(20)
i01.rightHand.wrist.setRest(20)
i01.startRightHand(rightPort)
i01.rightHand.thumb.setMinMax(0,160)
i01.rightHand.index.setMinMax(10,160)
i01.rightHand.majeure.setMinMax(40,170)
i01.rightHand.ringFinger.setMinMax(30,150)
i01.rightHand.pinky.setMinMax(0,160)
i01.rightHand.wrist.setMinMax(10,170)
i01.rightHand.thumb.map(0,180,0,160)
i01.rightHand.index.map(0,180,10,160)
i01.rightHand.majeure.map(0,180,40,170)
i01.rightHand.ringFinger.map(0,180,30,150)
i01.rightHand.pinky.map(0,180,0,160)
i01.rightHand.wrist.map(0,180,10,170)
i01 = Runtime.create("i01","InMoovArm")
i01.rightArm = Runtime.create("i01.rightArm","InMoovArm")
i01.rightArm.bicep.setRest(0)
i01.rightArm.rotate.setRest(110)
i01.rightArm.shoulder.setRest(90)
i01.rightArm.omoplate.setRest(0)
i01.rightArm.bicep.setMinMax(0,70)
i01.rightArm.rotate.setMinMax(40,168)
i01.rightArm.shoulder.setMinMax(20,160)
i01.rightArm.omoplate.setMinMax(0,100)
i01.rightArm.bicep.map(0,180,0,70)
i01.rightArm.rotate.map(0,180,40,168)
i01.rightArm.shoulder.map(0,180,20,160)
i01.rightArm.omoplate.map(0,180,0,100)
i01.startRightArm(rightPort)
i01.moveArm("right",0,110,90,0)
i01.leftArm = Runtime.create("i01.leftArm","InMoovArm")
#i01.leftArm.bicep.setRest(0)
#i01.leftArm.rotate.setRest(110)
i01.leftArm.shoulder.setRest(96)
i01.leftArm.omoplate.setRest(99)
i01.startLeftArm(leftPort)
#i01.leftArm.bicep.setMinMax(0,120)
#i01.leftArm.rotate.setMinMax(40,168)
i01.leftArm.shoulder.setMinMax(0,180)
i01.leftArm.omoplate.setMinMax(99,170)
i01 = Runtime.create("i01","InMoovHead")
i01.startHead(leftPort)
i01.head.neck.setRest(90)
i01.head.rothead.setRest(90)
i01.head.jaw.setRest(62)
i01.head.eyeY.setRest(90)
i01.head.eyeX.setRest(115)
i01.head.eyeY.setMinMax(80,100)
i01.head.eyeY.map(0,180,80,100)
i01.head.eyeX.setMinMax(100,130)
i01.head.eyeX.map(0,180,100,130)
i01.head.neck.setMinMax(0,180)
i01.head.rothead.setMinMax(0,180)
i01.head.jaw.setMinMax(73,62)
torso = i01.startTorso(leftPort)
torso.topStom.setMinMax(60,120)
torso.topStom.setRest(90)
opencv = i01.startOpenCV()
i01.startEyesTracking(leftPort)
i01.startHeadTracking(leftPort)
i01.eyesTracking.xpid.setPID(12.0,12.0,0.1)
i01.eyesTracking.ypid.setPID(12.0,12.0,0.1)
i01.headTracking.xpid.setPID(12.0,12.0,0.1)
i01.headTracking.ypid.setPID(12.0,12.0,0.1)
i01.eyesTracking.ypid.invert()
i01.startMouthControl(leftPort)
i01.mouthControl.setmouth(73,62)
i01.moveHead(90,90,80,80,73)
</param>
</mrl>
</oob></template>
</category>
<category><pattern>POWER UP</pattern>
<template>Attach All.
<oob>
<mrl>
<service>i01</service>
<method>powerUp</method>
</mrl>
</oob></template>
</category>
<category><pattern>POWER DOWN</pattern>
<template>Powering down.
<oob>
<mrl>
<service>i01</service>
<method>powerDown</method>
</mrl>
</oob></template>
</category>
<category><pattern>DETACH ALL</pattern>
<template>Detach All
<oob>
<mrl>
<service>i01</service>
<method>detach</method>
</mrl>
</oob></template>
</category>
<category><pattern>ATTACH ALL</pattern>
<template>Attaching all
<oob>
<mrl>
<service>i01</service>
<method>attach</method>
</mrl>
</oob></template>
</category>
</aiml>
randommove.aiml
<?xml version="1.0" encoding="UTF-8"?>
<aiml>
<category><pattern>RANDOMMOVE</pattern>
<template><oob>
<mrl>
<service>python</service>
<method>exec</method>
<param>
randommove()
</param>
</mrl>
</oob></template>
</category>
</aiml>
2. Use the following Python script and replace yourbotname with the name of your programAB bot, it includes the def for randommove. You can easily add your own def's here (don't forget to invoke them!)
from java.lang import String
def heard(data):
print "Sphinx Data:", data
yourbotname = Runtime.createAndStart("yourbotname", "ProgramAB")
yourbotname.startSession("ProgramAB", "default", "yourbotname")
sphinx = runtime.createAndStart("i01.ear","Sphinx")
pats = yourbotname.listPatterns("yourbotname")
sphinx_grammar = "|".join(pats)
sphinx.startListening(sphinx_grammar)
htmlfilter = Runtime.createAndStart("htmlfilter", "HtmlFilter")
mouth = Runtime.createAndStart("i01.mouth", "Speech")
mouth.setGoogleURI("http://thehackettfamily.org/Voice_api/api2.php?voice=Ryan&txt=")
sphinx.addTextListener(yourbotname)
sphinx.addListener("publishText", python.name, "heard", String().getClass());
yourbotname.addTextListener(htmlfilter)
htmlfilter.addTextListener(mouth)
holygrail = Runtime.createAndStart("holygrail", "WebGUI")
sphinx.attach(mouth)
def randommove():
i01.moveHand("right",50,50,50,60,50,50)
i01.moveArm("right",30,120,105,10)
i01.moveTorso(100,90,90)
i01.moveArm("left",0,90,96,99)
sleep(0.5)
i01.moveHand("right",50,50,50,60,50,20)
i01.moveArm("right",0,110,96,0)
i01.moveTorso(90,90,90)
i01.moveArm("left",0,90,90,90)
randommove()
3. If you want to talk to him using android, please follow these steps:
http://myrobotlab.org/content/voice-recognition-android-programab-mrl
Now you can talk to him using e.g. the Alice bot.
Here you can easy create or add/change aiml files: https://playground.pandorabots.com/en/
I hope it works for you folks, please feel free to ask any questions. Enjoy!
Just ignore me if you think I
Just ignore me if you think I am too negative but to me it looks like
1000 options to make that NOT worky
1 way to do it right
How can I split this thing up so e.g. I just have 1 common file that knows my InMoovs min/max settings and mappings
Replace the (for humans like me) hard to read XML sections with simpler commands?
Python for python , xml for xml..
Hi Juerg,
You're right, That syntax is bad. I believe a much better way to do it is to define the python functions in a python script and then invoke those functions from the oob tag.
This will avoid all sorts of issues with XML encoding and python syntax. So, in a python script you can do a
def myfunction():
# do some stuff..
pass
and in the AIML OOB tag you only need to pass
<oob>
<mrl>
<service>python</service>
<method>exec</method>
<param>myfuction()<param>
</mrl>
</oob>
I think this does a lot to keep the xml simpler...
Hopefully that seems a bit less error prone. I'm open to any feedback you might have for a better way to structure it.
Best,
-Kevin