Integrated movement service creation

Hello all.  If you havent kept up with my progress in the shoutbox, I am in the process of finishing  a highly advanced head mod  ( the "advanced inmoov head").  I have to control 28 servos using, for now,   2  16-channel servo drivers.

However, i need a service that will allow for the many servos ( there are at least 8 in the lips) in the head to be controlled simultaneously.  I also need to be able to save the positions of servos in a way similar to the InmoovGestureCreator and have the ability to  chain these "gestures" together to make complexed emotional movements on inmoov's face.  

Along with this advanced control over multiple servos, I need a to be able to dynamically change the limits of a servo depending on the position of another servo. For example, my  advanced inmoov eyes have mechanical limits due to the eyelids. When the eye is horizontally in one of the corners of the eye socket, it is unable to move much, if at all in the vertical direction without hitting the eyelids (just like a human eyeball). Thus, it is necessary to be able to change the limits of a servo (say the up and down servo for the eyes), depending on the position of another servo.    

@Calamity,  I heard from Kwatters that you've made great progress on an integrated movement service and he suggested I make this post so that all of us could discuss how to make this service a reality. A lot of us here on MRL, including myself, would appreciate any assistance you could offer.  

In any case, lets get to work !  :)

 

Alexinator40's picture

A github ticket was made

A github ticket was made about a week ago for brainstorming this concept. Comments can either be post here or there.    

https://github.com/MyRobotLab/myrobotlab/issues/228

calamity's picture

Hi Alexinator I would gladly

Hi Alexinator

I would gladly assist anyone who want assistance, be with the integrated movement service or any thing that I have some knowledge.

To do what you want with your advanced head, you could use a structure similar to what I have done with integrated movement service (or I think it sould be fairly easy to add it the the integrated movement service.

  • Have a service that define and keep track of the position of your part
  • the services runs threads that constantly computes the position of the part and adjust their position.

So to be more specific with your case, you could have a service that define and keep track of the position and current limits of your 'eyes' servo and a thread that compute the position and limits of the servo based on what your service know. ie if servo A is in position x, set the limits of servo B to x/y then move it to be inside those limits. 

I hope I'm somewhat clear the the strategy I describe. Personnaly, I like this because it could easily create behaviour instead of scripted gestures

Alexinator40's picture

Hey Calamity. I didnt

Hey Calamity. I didnt remember to ask this to you last night. Do you have source code for your integrated movement service you could provide us to look over? We want to see if we could use your code as a basis for a dynamic limits service, a servo orchestrator service, or both. We also would possibly like to generalize your code from just inmoov to any robot that uses mrl so many other users can improve their robots' movements.

calamity's picture

the

the service https://github.com/MyRobotLab/myrobotlab/blob/develop/src/main/java/org/myrobotlab/service/IntegratedMovement.java

all the other class relate to it

https://github.com/MyRobotLab/myrobotlab/tree/develop/src/main/java/org/...

hairygael's picture

Hello, Because you mention in

Hello,

Because you mention in the shoutbox not having played with codes yet, here is a script you could use to run some tests on your 27 servo head. This is not relevant with integrated movement service, but there is servo syncing for the eyelids.

It also can be usefull before the refactor of the servoOrchestrator is fully working.

 

#########################################
# Servo test by Gael For Alexinator40.py
# more info @: http://myrobotlab.org/service/Servo
#########################################
# uncomment for virtual hardware
# virtual = True

eyeXPin = 22
eyeYPin = 24
eyeLidRightPin = 12
eyeLidLeftPin = 13

# port = "/dev/ttyUSB0"
port = "COM15"

# start optional virtual arduino service, used for test
if ('virtual' in globals() and virtual):
    virtualArduino = Runtime.start("virtualArduino", "VirtualArduino")
    virtualArduino.connect(port)

# create a servo controller and a servo
arduino = Runtime.start("arduino","Arduino")
eyeX = Runtime.start("eyeX","Servo")
eyeY = Runtime.start("eyeY","Servo")
eyeLidRight = Runtime.start("eyeLidRight","Servo")
eyeLidLeft = Runtime.start("eyeLidLeft","Servo")

# initialize arduino
# linux or macos -> arduino.connect("/dev/ttyUSB0")
print("connecting arduino to serial port")
arduino.connect(port)

# servo01.setMinMax(0, 180)
eyeX.map(0, 180, 0, 180)
eyeY.map(0, 180, 0, 180)
eyeLidRight.map(0, 180, 0, 180)
eyeLidLeft.map(0, 180, 0, 180)

# set rest position
eyeX.setRest(90)
eyeY.setRest(90)
eyeLidRight.setRest(90)
eyeLidLeft.setRest(90)

# attach servo
print("attaching servo with pins to controller")
eyeX.attach(arduino.getName(), eyeXPin)
eyeY.attach(arduino.getName(), eyeYPin)
eyeLidRight.attach(arduino.getName(), eyeLidRightPin)
eyeLidLeft.attach(arduino.getName(), eyeLidLeftPin)

# auto disable - this enables (starts pwm) before a movement
# and disables (stops pwm) after a movement
eyeX.setAutoDisable(True)
eyeX.disableDelayIfVelocity=1000 # grace period for autoDisable
eyeY.setAutoDisable(True)
eyeY.disableDelayIfVelocity=1000
eyeLidRight.setAutoDisable(True)
eyeLidRight.disableDelayIfVelocity=1000
eyeLidLeft.setAutoDisable(True)
eyeLidLeft.disableDelayIfVelocity=1000

# speed changes
print("speed changes")
eyeX.setVelocity(80) ## Low velocity
eyeY.setVelocity(80)
eyeLidRight.setVelocity(80)
eyeLidLeft.setVelocity(80)

eyeX.moveTo(0) # we cannot use moveToBlocking if servo velocity is set to -1 ( max ) !!
eyeY.moveTo(180)
sleep(2)

# sync eyeLidRight with eyeLidLeft
# now eyeLidRight will be a slave to eyeLidLeft
print("syncing eyeLidRight with eyeLidLeft")
eyeLidRight.sync(eyeLidLeft)

eyeLidLeft.moveTo(10)
sleep(0.5)

eyeLidLeft.moveTo(179)
sleep(0.5)

eyeLidLeft.moveTo(10)
sleep(0.5)

# moving to rest position
print("eyeLidLeft rest")
eyeLidLeft.rest()
sleep(2)

Alexinator40's picture

Hey Gael! Thanks for

Hey Gael! Thanks for commenting and providing this helpful script ! :)  Although the advanced head actually has 4 eyelids that can be controlled, I am sure I can figure out how to edit the code you provided to test the eyelid and eye functionality! I hope you will like my mod when its released! By the way, my advanced head will support your new neck, though i might have to make a minor modification or two to the neck base (where the pistons attach to) so that I can fit all the servos in :)