InMoov Service help wanted

I'm looking for some friendly help to modify the InMoov services :-)

I'd like to transfer all the head/neck functions to a new Arduino board mouned in the head. I thought this was going to be simple, just pass the new port to the head service and it will create the new Arduino service that all the servos can be attached to, but it doesn't seem that simple?

I can't find where the Arduino is created? I can see that the InMoov service keeps a HASH list of Arduinos and port numbers, but can't quite see where the Arduino is created.

Is there a documnet that explains how all this works or could someone point me in the right direction please?

Regards

Andrew

 

GroG's picture

Hi rekabuk, Thanks for the

Hi rekabuk,

Thanks for the post,
This is probably long overdue, but I'll try to explain how to tweak DNA (Descriptions of Neighboring Autotoma) 
 

The head arduino is created in the InMoovHead service.

It's this line :

arduino = (Arduino) createPeer("arduino");

These are "peer" methods.  Peer methods use peer "keys" - in this case the peer key is "arduino" ..
Peer keys are used as a reference from a service to another service.
In this case its a reference of some Arduino service from the InMoovHead service.

The Peer system allows composite services to reference and control the actual names of the services, while the underlying services use 'simple' key references.

Composite services are services which references services which reference more services.  At the top typically there is something which orchestrates all of the things below it.  In this case the InMoov service is the orchestrator of all the services below it.  InMoov service is allowed to know "everything", but the lower level services know nothing of the higher level services.  This is important because it allows the complexity of higher level orchestration at the same time the lower level services can operate indepenently of the higher ones.  In a short statement, "InMoov service can control everything, InMoovHead can operate by itself, so can Servo etc etc..

You can think of each service having a blueprint of itself, so it may control it's "peers" or "peers" of "peers" successfully.

Lets look at InMoovs blueprint.
I find the WebGui easiest to do this - because the json is formatted in the browser.

This the InMoov service set of peer "keys" - 
http://localhost:8888/api/service/runtime/buildDnaKeys/i01/InMoov 

["i01.ear","i01.eyesTracking","i01.eyesTracking.controller","i01.eyesTracking.opencv","i01.eyesTracking.x","i01.eyesTracking.y","i01.head","i01.head.arduino","i01.headTracking","i01.headTracking.controller","i01.headTracking.opencv","i01.headTracking.x","i01.headTracking.y","i01.integratedMovement","i01.jmonkeyEngine","i01.leftArm","i01.leftArm.arduino","i01.leftHand","i01.leftHand.arduino","i01.mouth","i01.mouthControl","i01.mouthControl.arduino","i01.mouthControl.jaw","i01.mouthControl.mouth","i01.opencv","i01.openni","i01.pid","i01.python","i01.rightArm","i01.rightArm.arduino","i01.rightHand","i01.rightHand.arduino","i01.torso","i01.torso.arduino"]

These are the "keys" (not actual names) of all the service peers of an InMoov service named i01.  These services are a list of all the things InMoov can 'possibly' control.

Notice there is a :
"i01.head.arduino" and
"i01.eyesTracking.controller" and
"i01.headTracking.controller"

Are there three 3 Arduinos in the head ?  No. 

Most people do not want to have to buy 3 Arduinos to support the InMoovHead servos, the Tracking service for the eyes and the Tracking service for the head.  But we don't want to give up the control of referencing each by its key.  So what do we do ?

Share !

We allow the InMoov service to modify the "actual names" of the service.  In MyRobotLab-Land there one and only one "actual name" of a service.  One service - one name .. that's the law.  But the keys allow for a form of aliasing.

The default way the InMoov service is expected to run is with a single Arduino controlling these 3 sub-services.  So, within the Java code of InMoov, sub-services are told to share.

You can find these 3 lines (and others)  in the getMetaData method of the InMoov service.

    meta.sharePeer("eyesTracking.controller", "left", "Arduino", "shared head Arduino");
    meta.sharePeer("headTracking.controller", "left", "Arduino", "shared head Arduino");
    meta.sharePeer("head.arduino", "left", "Arduino", "shared left arduino");

These lines are a default way to modify the original keys so that 3 of the keys point to the same arduino.
The arduino's actual name will be i01.left

You can query how the InMoov service will modify the keys with the following url (it lists all modifications)

http://localhost:8888/api/service/runtime/mergeDna/i01/InMoov 

"i01.eyesTracking.controller": {"key": "eyesTracking.controller","actualName": "i01.left","fullTypeName": "org.myrobotlab.service.Arduino","comment": "shared head Arduino","isRoot": false}

"i01.headTracking.controller": {"key": "headTracking.controller","actualName": "i01.left","fullTypeName": "org.myrobotlab.service.Arduino","comment": "shared head Arduino","isRoot": false}

"i01.head.arduino": {"key": "head.arduino","actualName": "i01.left","fullTypeName": "org.myrobotlab.service.Arduino","comment": "shared left arduino","isRoot": false}

 

In fact you'll find many entries who's alias key maps to i01.left ...  because many of the services share this resource.  Same goes for Tracking service. We have 2 Tracking services but only one OpenCV service .. same thing.

All of this was designed so that much of the structure and actual build can vary, without having to modify code.  If someone was to hack up the "code" for there specific build of InMoov most likely it would break others who had a different design.  So next question should be .. How do I modify these mappings ?

Keep in mind two important laws of MRL :
"Every service has a unique name" and
"Once a service is created with a name it can not change"

First lets go over the sequence of creation :

  1. DNA Blue-Print of "default" is created from code - This happens in getMetaData() method
  2. Composite Service (InMoov) is created and allowed to modify internal structure - (sharing in getMetaData()
  3. Composite Service creates and starts sub-services - actual names cannot  change now

We have access to modify DNA between 1. & 2. AND the Composite Service will not modify a mapping if one already exists.

The easiest way to modify the dna is the reserveRoot(key, actualName, type, comment) method.

You want coerce these services to use your new Arduino.  So it only takes 3 lines of code (in Python), before anything else is done.

# put in reserves
python.reserveRoot("i01.eyesTracking.controller","MyNewArduino", "Arduino", "want new one")
python.reserveRoot("i01.headTracking.controller","MyNewArduino", "Arduino", "want new one")
python.reserveRoot("i01.head.arduino","MyNewArduino", "Arduino", "want new one")

Now you'll see the DNA mappings change.
http://localhost:8888/api/service/runtime/mergeDna/i01/InMoov 

"i01.eyesTracking.controller": {"key": "i01.eyesTracking.controller","actualName": "MyNewArduino","fullTypeName": "org.myrobotlab.service.Arduino","comment": "want new one","isRoot": false}

"i01.head.arduino": {"key": "i01.head.arduino","actualName": "MyNewArduino","fullTypeName": "org.myrobotlab.service.Arduino","comment": "want new one","isRoot": false}

"i01.headTracking.controller": {"key": "i01.headTracking.controller","actualName": "MyNewArduino","fullTypeName": "org.myrobotlab.service.Arduino","comment": "want new one","isRoot": false}

So, now when I create the InMoov service i01 and start the Head and Arm some of the services use the original i01.left and some now use MyNewArduino.  You can create MyNewArduino before you create all the other services if you want connect it to a different port.  You'll want to do this, because otherwise there will be port contention (Arduinos can share ports).

Be aware, you could also change the "Type" to be any type of ServoController ..  e.g. Adafruit16CServoDriver instead of the Arduino.

With the following code :

# virtual arduinos no real arduinos on hand
v1 = Runtime.start('v1','VirtualArduino')
v1.connect('COM4')
v2 = Runtime.start('v2','VirtualArduino')
v2.connect('COM5')

# start i01, head & left arm
i01 = Runtime.start('i01', 'InMoov')
i01.startHead("COM4")
i01.startLeftArm("COM5")
 

Now, I get left arm stuff using the original i01.left arduino and everything in the head using MyNewArduino

Although I could have said - use these 3 lines, I thought it would be beneficial to explain all the parts. And hopefully with that knowledge you can "re-mix" services to your desire.

Cheers.

References:

 

rekabuk's picture

Wow thanks Grog, That's a

Wow thanks Grog,
That's a real help, although I think it will take me a week to digest it :0)
Really greatfull for your time.
Regards
Andrww

rekabuk's picture

Hi Grog, I spent the weekend

Hi Grog,

I spent the weekend doing "family stuff" so haven't looked in great deal, but I have been mulling this over and trying to work out where in my script to add the new lines?

The script I've been using is from the InMoov website(http://inmoov.fr/how-to-start-myrobotlab/), it creates a MyRobotLab InMoov runtime service which I beleive runs the main method in the InMoov class? This creates the two vitual ports you mentioned at teh end of your email, although they are fixed at COM1 and COM2 so I'm not sure what Linux does at this point?

Once all InMoove components are created in the script, the MyrobotLab InMoov service is started and later InMoov "i01.startAll(leftPort, rightPort)" is called which starts the head with the "leftPort", which I don't think is what I want?

I don't want to start the head until I have reassigned the port and set the correct servo pins, so should my script start the head and eveything else without calling the InMoov.startAll() method?

Sorry, I can see from your email what needs to be done, I just can't see how it fits in with the startup sequence, without starting the head before the port and servo pins are reassigned?

Your's, just a little confussed

Andrew

rekabuk's picture

Progress :-)

OK, so I have re-arranged the script a little and am concentrating on the head/neck. I get my 3 arduinos, but can't check the DNA. When I run either of the DNA commands GroG suggested I get a long error - Can anybody give me some advice on this error please?

Command:

http://localhost:8888/api/service/runtime/buildDnaKeys/i01/InMoov

Response:

{"msgId":1492582029029,"name":"webgui","sender":"webgui","sendingMethod":"","historyList":[],"method":"onHandleError","data":[{"name":"webgui","level":"error","key":"could not find Runtime.buildDnaKeys(ordinal 2) in declared methods","detail":"------\r\njava.lang.NoSuchMethodException: could not find Runtime.buildDnaKeys(ordinal 2) in declared methods\n\tat org.myrobotlab.codec.MethodCache.getCandidateOnOrdinalSignature(MethodCache.java:68)\n\tat org.myrobotlab.service.WebGui.handle(WebGui.java:682)\n\tat org.atmosphere.nettosphere.Config$Builder$1.onRequest(Config.java:411)\n\tat org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:206)\n\tat org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:108)\n\tat org.atmosphere.nettosphere.BridgeRuntime$2.suspended(BridgeRuntime.java:203)\n\tat org.atmosphere.container.NettyCometSupport.service(NettyCometSupport.java:52)\n\tat org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:2242)\n\tat org.atmosphere.nettosphere.BridgeRuntime.handleHttp(BridgeRuntime.java:547)\n\tat org.atmosphere.nettosphere.BridgeRuntime.messageReceived(BridgeRuntime.java:271)\n\tat org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)\n\tat org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)\n\tat org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791)\n\tat org.jboss.netty.handler.stream.ChunkedWriteHandler.handleUpstream(ChunkedWriteHandler.java:142)\n\tat org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)\n\tat org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791)\n\tat org.jboss.netty.handler.codec.http.HttpChunkAggregator.messageReceived(HttpChunkAggregator.java:145)\n\tat org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)\n\tat org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)\n\tat org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791)\n\tat org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296)\n\tat org.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:459)\n\tat org.jboss.netty.handler.codec.replay.ReplayingDecoder.callDecode(ReplayingDecoder.java:536)\n\tat org.jboss.netty.handler.codec.replay.ReplayingDecoder.messageReceived(ReplayingDecoder.java:435)\n\tat org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)\n\tat org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)\n\tat org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:559)\n\tat org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)\n\tat org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)\n\tat org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:88)\n\tat org.jboss.netty.channel.socket.nio.AbstractNioWorker.process(AbstractNioWorker.java:108)\n\tat org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:337)\n\tat org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:89)\n\tat org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178)\n\tat org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)\n\tat org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)\n\tat java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)\n\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)\n\tat java.lang.Thread.run(Thread.java:745)\n------\r\n"}]}
GroG's picture

"could not find

"could not find Runtime.buildDnaKeys(ordinal 2) in declared methods"

means the method doesn't exist in that version.

Sorry, didn't see your version in this post, I assumed wrongly that its the latest.
Everything I posted relates to the version I keep running, which is the latest.  But it sounds like you got it working regardless.

if you give me your version number I can look it up ...

GroG's picture

Is it functional the way you

Is it functional the way you want ? Can you get all 3 Arduino's working or are you still having issues with that ?

Also, I don't know your feeling about trying to keep up with the latest.  If you use VirtualArduino's there is the potential of testing what you want to do without risking 'real' hardware.

GroG's picture

Also if you intend to try the

Also if you intend to try the latest I usually recommend using another directory.

On my system I have one directory for each version I'm interested in.

e.g.

~/mrl.1743
~/mrl.2033
~/mrl.2034

this leaves everything in your previous installation the same as it was

rekabuk's picture

Starting to work :-)

Different directories? I'm having enough trouble with git and using the head :-)  I'm happy here at the moment - I normally use SVN and can't quite get my head round git and using different directories.

I created my new Arduino and added the 3 lines you mentioned:

#################
headArd = Runtime.createAndStart("headArd", "Arduino")
headArd.setBoardUno()
headArd.connect(headPort)
#################
python.reserveRoot("i01.eyesTracking.controller","headArd", "Arduino", "want new one")
python.reserveRoot("i01.headTracking.controller","headArd", "Arduino", "want new one")
python.reserveRoot("i01.head.arduino","headArd", "Arduino", "want new one")
 

Then created the InMoow services and used "i01.startAll(leftPort, rightPort)" to start everything, this almost works! All the head servos are on my new Arduino :-D     but there is an error when startMouthControl is called to attach to the jaw servo (well I think that's what is happening):

12:40:08.941 [i01.left] INFO  class org.myrobotlab.service.Arduino - i01.left /dev/ttyACM0 getVersion

12:40:08.942 [i01.left] INFO  c.myrobotlab.framework.Service - i01.left info i01.left.serial connected on /dev/ttyACM0 responded version 40 ... goodtimes...
12:40:08.942 [i01.left] INFO  c.myrobotlab.framework.Status - publishVersion 40
12:40:08.945 [python.interpreter.2] ERROR c.myrobotlab.framework.Service - python error PyException - null Traceback (most recent call last):
  File "<string>", line 211, in <module>
at org.myrobotlab.service.Arduino.servoAttach(Arduino.java:2312)
at org.myrobotlab.service.InMoov.startMouthControl(InMoov.java:1083)
at org.myrobotlab.service.InMoov.startAll(InMoov.java:942)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
I still can't get any of the DNA displays to work. 
 
And I really can't get my head round why the 3 lines need to be first, before anything alse is created?????
 
Andrew

 

rekabuk's picture

Cannot find device

In InMoov.startMouthControl()  line 1083, there is a call to attah the servo, but if you step into the attach function it gives an error cannot find i01.head.jaw, although it does exist in the GUI.

Here is my script:

 

from java.lang import String
import threading
import time
import random
from org.myrobotlab.net import BareBonesBrowserLaunch
##
import urllib, urllib2
import json
 
from datetime import datetime
#######################
import io
import itertools
import textwrap
import codecs
import socket
import os
import shutil
import hashlib
import subprocess
import csv
from subprocess import Popen, PIPE
 
#############################################################
# This is the InMoov script
# InMoov is powered by MyRobotLab
# Initially we'll start simple
# It will use ProgramAB & Webkit for all interactions with
# the bot.
#############################################################
# All bot specific hardware configuration goes here.
leftPort = "/dev/ttyACM0"
rightPort = "/dev/ttyACM1"
headPort = "/dev/ttyACM2"
 
gesturesPath = "/home/andrew/inmoov/ProgramAB/gestures"
 
aimlPath = "/home/andrew/inmoov/ProgramAB"
aimlBotName = "Eric"
aimlUserName = "Andrew"
#botVoice = "Ryan"
#############################################################
# LANGUAGE ( FR/EN )
lang="EN"
#Voice="dfki-spike-hsmm" 
 
#ACB This is the default InMoov voice
Voice="cmu-slt-hsmm" # Default female for MarySpeech 
 
#ACB - This is my preferred voice
#Voice="cmu-bdl-hsmm" #Male US voice.You need to add the necessary file.jar to myrobotlab.1.0.XXXX/library/jar
 
#https://github.com/MyRobotLab/pyrobotlab/blob/ff6e2cef4d0642e47ee15e353ef934ac6701e713/home/hairygael/voice-cmu-bdl-5.2.jar
#Voice="upmc-pierre-hsmm" #French voice
 
voiceType = Voice
 
##Create your free Id and key https://datamarket.azure.com/dataset/bing/microsofttranslator
client_id = "your_id"
client_secret = "yoursecret_key"
 
global human
global inmoov
global weathervar
global walkingThread
#############################################################
 
# toggle to only load program ab  and skip the inmoov services
startMyWay = False
startInMoov = True
 
######################################################################
# helper function help debug the recognized text from webkit/sphinx
######################################################################
def heard(data):
  print "Speech Recognition Data:"+str(data)
 
######################################################################
#
# MAIN ENTRY POINT  - Start and wire together all the services.
#
######################################################################
 
# launch the swing gui?
# gui = Runtime.createAndStart("gui", "GUIService");
 
######################################################################
# Create ProgramAB chat bot ( This is the inmoov "brain" )
######################################################################
#neopixel = Runtime.createAndStart("neopixel","Serial")
#neopixel.connect("COM3", 57600, 8, 1, 0)
inmoovWebKit = Runtime.createAndStart("inmoovWebKit", "ProgramAB")
inmoovWebKit.setPath(aimlPath)
inmoovWebKit.startSession(aimlUserName, aimlBotName)
 
######################################################################
# Html filter to clean the output from programab.  (just in case)
htmlfilter = Runtime.createAndStart("htmlfilter", "HtmlFilter")
 
######################################################################
# mouth service, speech synthesis
mouth = Runtime.createAndStart("i01.mouth", "MarySpeech")
#mouth.setVoice(botVoice)
mouth.setVoice(voiceType)
#Volume(amount=2.0)
#TractScaler(amount=1.4)
#F0Scale(f0Add=2.0)
#F0Add(f0Add=60.0)
#Robot(amount=0.0)
#Rate(amount=3.75)
#Whisper(amount=100.0)
#Stadium(amount=100.0)
#Chorus(delay=1.466;amp1=0.54)
#FIRFilter(type=3;fc1=500.0;fc2=2)
#mouth.setAudioEffects("Volume(amount=1.75) + TractScaler(amount=0.95) + F0Scale(f0Add=3.0)")
#mouth.setLanguage(lang)
 
######################################################################
# the "ear" of the inmoov TODO: replace this with just base inmoov ear?
ear = Runtime.createAndStart("i01.ear", "WebkitSpeechRecognition")
ear.addListener("publishText", python.name, "heard");
ear.addMouth(mouth)
######################################################################
WebkitSpeechRecognitionFix = Runtime.start("WebkitSpeechRecognitionFix","Clock")
WebkitSpeechRecognitionFix.setInterval(1000)
WebkitSpeechRecognitionFix.startClock()
######################################################################
# MRL Routing webkitspeechrecognition/ear -> program ab -> htmlfilter -> mouth
######################################################################
ear.addTextListener(inmoovWebKit)
inmoovWebKit.addTextListener(htmlfilter)
htmlfilter.addTextListener(mouth)
######################################################################
#Gets the battery level
level = Runtime.getBatteryLevel()
 
#################
headArd = Runtime.createAndStart("headArd", "Arduino")
headArd.setBoardUno()
headArd.connect(headPort)
 
#################
python.reserveRoot("i01.eyesTracking.controller","headArd", "Arduino", "want new one")
python.reserveRoot("i01.headTracking.controller","headArd", "Arduino", "want new one")
python.reserveRoot("i01.head.arduino","headArd", "Arduino", "want new one")
 
 
######################################################################
# Start up the inmoov and attach stuff.
######################################################################
i01 = Runtime.create("i01", "InMoov")
 
##############
head = Runtime.create("i01.head","InMoovHead")
 
##############
torso = Runtime.create("i01.torso", "InMoovTorso")
 
##############
leftHand = Runtime.create("i01.leftHand","InMoovHand")
 
###############
leftArm = Runtime.create("i01.leftArm","InMoovArm")
 
################
rightHand = Runtime.create("i01.rightHand","InMoovHand")
 
#################
rightArm = Runtime.create("i01.rightArm","InMoovArm")
 
#################
i01 = Runtime.start("i01","InMoov")
i01.setMute(False)
 
################# 
if startMyWay:
   i01.startMouth();
   i01.startHead(headPort, "UNO");
   i01.startEar();
 
   i01.startMouthControl(headPort);
 
   i01.mouthControl.setmouth(43,95)
   print("Test")
   i01.head.neck.attach(headPort, 7)
 
#################
   i01.startEyesTracking(headPort, 22, 24)
   i01.startHeadTracking(headPort)
 
#################
   #to tweak the default PID values
   i01.eyesTracking.pid.setPID("eyeX",12.0,1.0,0.1)
   i01.eyesTracking.pid.setPID("eyeY",12.0,1.0,0.1)
   i01.headTracking.pid.setPID("rothead",5.0,1.0,0.1)
   i01.headTracking.pid.setPID("neck",5.0,1.0,0.1)
 
#################
   #i01.startRightArm(rightPort)
   #i01.startRightHand(rightPort)
   #i01.startLeftArm(leftPort)
   #i01.startLeftHand(leftPort)
 
   #i01.startTorso(leftPort)
 
#################
   #i01.startPIR(leftPort,23)
 
elif startInMoov:
 
   i01.startAll(leftPort, rightPort)
   #i01.startMouth()
   #i01.startMouthControl(leftPort)
   i01.mouthControl.setmouth(43,95)
#################
   #i01.startEyesTracking(leftPort)
   #i01.startHeadTracking(leftPort)
#################
   #to tweak the default PID values
   i01.eyesTracking.pid.setPID("eyeX",12.0,1.0,0.1)
   i01.eyesTracking.pid.setPID("eyeY",12.0,1.0,0.1)
   i01.headTracking.pid.setPID("rothead",5.0,1.0,0.1)
   i01.headTracking.pid.setPID("neck",5.0,1.0,0.1)
#################
   #i01.startEar()
   #i01.startRightArm(rightPort)
   #i01.startRightHand(rightPort,"atmega2560")
   #i01.startLeftArm(leftPort)
   #i01.startLeftHand(leftPort)
   i01.startTorso("COM20")
#################
   #i01.startPIR("COM20",23)
 
else:
  i01.mouth = mouth
    
# InMoov has a forward servo, i'm adding
#forwardServo = Runtime.start("forwardServo","Servo")
#directionServo = Runtime.start("directionServo","Servo")
 
#rollneck = Runtime.start("rollneck","Servo")
right = Runtime.start("i01.right", "Arduino")
right.connect(rightPort)
right.setBoardMega()
 
#directionServo.attach(right, 24)
#forwardServo.attach(right, 26)
 
#rollneck.attach(right,12)
#rollneck.setRest(90)
#rollneck.moveTo(90)
 
 
#################
#Sets FaceRecognizer
#fr=i01.opencv.addFilter("FaceRecognizer")
#lastName=fr.getLastRecognizedName()
#################
##Velocity settings
 
head.eyeX.setVelocity(0)
head.eyeY.setVelocity(0)
 
head.neck.setVelocity(0)
head.rothead.setVelocity(0)
head.jaw.setVelocity(0)
 
#torso.topStom.setVelocity(0)
#torso.midStom.setVelocity(0)
#torso.lowStom.setVelocity(5)
 
#rightHand.thumb.setVelocity(25)
#rightHand.index.setVelocity(25)
#rightHand.majeure.setVelocity(25)
#rightHand.ringFinger.setVelocity(25)
#rightHand.pinky.setVelocity(25)
#rightHand.wrist.setVelocity(25)
 
#leftHand.thumb.setVelocity(25)
#leftHand.index.setVelocity(25)
#leftHand.majeure.setVelocity(25)
#leftHand.ringFinger.setVelocity(25)
#leftHand.pinky.setVelocity(25)
#leftHand.wrist.setVelocity(25)
 
#leftArm.bicep.setVelocity(30)
#leftArm.rotate.setVelocity(30)
#leftArm.shoulder.setVelocity(30)
#leftArm.omoplate.setVelocity(30)
 
#rightArm.bicep.setVelocity(30)
#rightArm.rotate.setVelocity(30)
#rightArm.shoulder.setVelocity(30)
#rightArm.omoplate.setVelocity(30)
 
######################################################################
# Launch the web gui and create the webkit speech recognition gui
# This service works in Google Chrome only with the WebGui
#################################################################
webgui = Runtime.create("webgui","WebGui")
webgui.autoStartBrowser(false)
webgui.startService()
BareBonesBrowserLaunch.openURL("http://localhost:8888/#service/i01.ear")
 
######################################################################
# END MAIN SERVICE SETUP SECTION
######################################################################
if lang=="EN":
   ear.setLanguage("en-EN")
python.subscribe(ear.getName(),"publishText")
 
######################################################################
# Helper functions and various gesture definitions
######################################################################
#i01.loadGestures(gesturesPath)
 
rekabuk's picture

Latest

Sorry missed this bit - I beleive I am running the latest from git 2017.4.19. That's for myrobotlab, I think repo is the latest to.

Can't try the DNA stuff at the moment as my script crashes...

Thanks for your patience :-D

GroG's picture

Hi Andrew, I've been

Hi Andrew,

I've been distracted a bit with other stuffs..

It looks like you made some progress, are you stuck at another issue ?

In regards to DNA and such - its a design to manage configuration "before" stuff is created or started .. but really there's no reason why you can't take what was created by the InMoov service and modify it after its created.

InMoov is a composite service, it is supposed to ease the contruction, configuration, and orchestration of other services .. but by the nature of MRL framework you can really grab any service you want and modify it to your desire.

If you want to go this way .. start InMoov up with errors ..  and with the rest of your script detach all the servos you want on your new script .. and re-attach them to the new arduino..

Servos are controlled by the composite InMoov services, after conneting and attaching the Arduinos are pretty much ignored.

servoToMove = Runtime.start("servoname","Servo")  <- will not create a "new" servo if it already exists ..  The "name law" in MRL is every service MUST have a unique name.  So this will give you a reference to the servo.  You can get a reference to any Service this way.

Once you do that you can manipulate it to your desire.

rekabuk's picture

Hi GroG I had some success

Hi GroG
I had some success yesterday. But I didn't use DNA, I created my own inmoov.startall() in the python script and for the moment I've modified the services to use the pins that match my robot.
All the servos work on the right Arduino from the gui, but mouth control won't start because it can't attach the servo - it reports "device not found" for the servo, although it does exist as far as I can see.
I'll try and send some more info later, like a log...
Thanks for your help I'm getting closer.
Andrew

rekabuk's picture

I don't begin to undersand....

but it works :-)

In the InMoov servce, line 1083 I removed the line that attaches the servo to the arduino because it seemed this was already done when mouthContol is created or started or constructed or something.

Anyway now I have removed the line that failed because it couldn't find the device, my robot mouth moves as it talks #:0)

However, I do get a "pyException null" error at the bottom of my MyRobotLab GUI?

Andrew

rekabuk's picture

Turns out it only works sometimes....

Sometimes I have to fiddle with the swing gui to get things running :-(