ProgramAB , AIML and MRL Support for OOB tags.

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/CallMomOOB...

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


#file : home/kwatters/Lloyd.InMoov.ProgramAB.py edit raw
from java.lang import String
 
######################################################################
# A helper function to print the recognized text to the python window.
# semi-useful for debugging.
######################################################################
def heard(data):
  print "Sphinx Data:", data
 
######################################################################
# Create ProgramAB chat bot
######################################################################
lloyd = Runtime.createAndStart("lloyd", "ProgramAB")
lloyd.startSession("ProgramAB", "default", "lloyd")
 
######################################################################
# create the speech recognition service
######################################################################
sphinx = runtime.createAndStart("i01.ear","Sphinx")
pats = lloyd.listPatterns("lloyd")
# create the grammar for the speech recognition service
sphinx_grammar = "|".join(pats)
sphinx.startListening(sphinx_grammar)
 
######################################################################
# create the html filter to filter the output of program ab
######################################################################
htmlfilter = Runtime.createAndStart("htmlfilter", "HtmlFilter")
 
######################################################################
# create the speech to text service (named the same as the inmoov's)
######################################################################
mouth = Runtime.createAndStart("i01.mouth", "Speech")
 
######################################################################
# MRL Routing   sphinx -> program ab -> htmlfilter -> inmoov
######################################################################
# add a route from Sphinx to ProgramAB
sphinx.addTextListener(lloyd)
# debugging in python route.
sphinx.addListener("publishText", python.name, "heard", String().getClass());
 
# Add route from Program AB to html filter
lloyd.addTextListener(htmlfilter)
# Add route from html filter to mouth
htmlfilter.addTextListener(mouth)
 
# make sure the ear knows if it's speaking.
sphinx.attach(mouth)
  

 


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
kwatters's picture

working example of OOB AIML tags and MRL.

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")
 
 
 
GroG's picture

Thanks for that Kwatters !

Thanks for that Kwatters !

kwatters's picture

Test Driver script:   from

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)
Mastablasta's picture

Some tests with AIML

Looks fine so far. Elias in controllable thru programAB/Superbot.

The shoulder issue is already solved.

 

 

kwatters's picture

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.

 

Mastablasta's picture

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!

juerg's picture

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?

kwatters's picture

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