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]]
  

 

kwatters

10 years 1 month ago

Here's an example of AIML that will respond with some text and invoke the "exec" method on the "python" to print hello world into the python console window.  (kinda a silly exapmle, but it does show it works.)
 
This is an example to build a chat bot named "lloyd"
 
Create a file called  myrobot.aiml  in the ProgramAB/bots/lloyd directory.
 
<?xml version="1.0" encoding="UTF-8"?>
<aiml>
<category><pattern>TEST OOB</pattern>
<template>
 A response to OOB tag. 
 <oob>
   <mrl>
     <service>python</service>
     <method>exec</method>
      <param>print "hello world"</param>
   </mrl>
 </oob>
</template>
</category>
</aiml>
 
The following python code is an example of how to use this
lloyd = Runtime.createAndStart("lloyd", "ProgramAB")
lloyd.startSession("ProgramAB", "default", "lloyd")
resp = lloyd.getResponse("TEST OOB")
 
 
 

Test Driver script:

 

from java.lang import String
 
lloyd = Runtime.createAndStart("lloyd", "ProgramAB")
lloyd.startSession("ProgramAB", "default", "lloyd")
pats = lloyd.listPatterns("lloyd")
sphinx_grammar = "|".join(pats)
print sphinx_grammar
ear = runtime.createAndStart("speech","Sphinx")
ear.startListening(sphinx_grammar)
ear.addListener("publishText", python.name, "heard", String().getClass());
lloyd.addTextPublisher(ear)
 
def heard(data):
  print "Sphinx Data:", data
  # lloyd.getResponse(data)

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.

 

Mastablasta

10 years ago

In reply to by kwatters

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=&quot;)

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 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?

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