Realizing how many script lines we have that use set<xx>Speed I thought of a workaround for the deprecated speed setting.

I am replacing all "i01.set<xx>Speed(...) in all py files with a call to set<xx>Speed() function.

I have added gesture files named set<xx>Speed for the parts that look like this:

def setArmSpeed(side, b, r, s, o):
  i01.setArmVelocity(side, b*15, r*15, s*15, o*15)

where 15 is the maxVelocity of the sub parts.

kwatters

6 years 7 months ago

If you remove those methods you will break backwards compatablility.

Also.. the conversion from the old style speed control and the velocity control is not linear!

So.. I don't like this idea. Please do not do this. It is not correct. Please review the existing mapping function in the Java code.

Might be a misunderstanding - e.g. the "setHandSpeed(...)" function is marked deprecated. But in the standard gestures we have over 100 lines calling setHandSpeed(...)!

So your opinion is to step through all the files and replace them with correct "setHandVelocity()" entries? A huge task. I will stick to my method until we can have a replacement for the setSpeed that allows to specify a percentage of the max velocity for a servo.

To me its much easier to say "move it half of max speed" than finding an apropriate absolute velocity-value for each servo in every gesture.

There was a long discussion about this subject.

The setSpeed has two problems. 

1. The "max speed" is undefined. so per say, half max speed is also undefined. SetSpeed(0.99) should result in almost the same speed as setSpeed(1), but it doesn't.

2. setSpeed(0.75) should result in 3/4 of 1 or .99, but it doesn't. It's not linear.

So what speed you get is totally depending on what servo you use, So you can never know what speed you will get for any gesture. What works for you will only work for people using the same servo.

That's the reason for the change from setSpeed to setVelocity. 

When setVelocity is used you get the same speed, independant of what servo you use, as long as the servo can keep up with the speed.

 

calamity

6 years 7 months ago

as kwatters and Mats explain, setSpeed have many problems that are hard to understand for the common user and that's why it have been deprecated in favor of setVelocity.

That said, setSpeed is still too widely used to be totally removed anytime soon. So I still have many gestures using the setSpeed, but I do new one with setVelocity or change it when I modify a gesture.

So I don't think it worth changing all your gesture right now, but you should start to use the setVelocity as you do new stuff. 

I insist on being misunderstood!

what I did is creating a python function for the main robot parts (arm, hand, head, eye, torso)

def setArmSpeed(side, b, r, s, o):
  i01.setArmVelocity(side, b*15, r*15, s*15, o*15)

I agree it could be improved by using the maxVelocity values of the servos, e.g.

b*i01.leftArm.bicep.maxVelocity

instead of my constant 15.

I then did a "replace in files" of all i01.setArmSpeed( with setArmSpeed( in the gestures folder.

This results in calling my setArmSpeed python function with e.g. the factors all set to 0.8.

My gestures are now calling the new setArmVelocity java routine through my python function with the factors 0.8.

As this might still not be 100% perfect it is a significant improvement for getting a relatively exact velocity and it avoids using the depricated java setArmSpeed routine?

And in addition - I do not understand why the setArmSpeed routine got depricated instead of making maxVelocity values mandatory and use the same logic of applying partial speeds as partial maxVelocity values.

Ok.. let me start by saying, you are correct that the speed/velocity thing is a mess and it's confusing to people.  I think everyone here agrees with that.

Next, The switch between speed & velocity a few months back really confused a lot of people and made them very frustrated with MyRobotLab for a number of reasons, but mostly because servos moved "slowly" and that the old style setSpeed didn't work anymore.  

Adding , yet another method for speed / velocity control isn't the answer.  The proper answer is to do it in a consistent and documented way that is unit tested and consistent in how it works.  Additional methods for doing this is only making things more complex, not less.  The goal here should be simple, well documented, and stable.  When I say stable, I mean th e interfaces will NOT change going forward unless there is a seriously good reason to change them.  Having stable interfaces is really important if anyone is going to develop software against them.

Next,  I want to remind you that the relationship between the old style speed and the new style velocity control is not linear.  And as a matter of fact, the old style speed and the new style velocity control is aready being mapped programmaticly.  Please review this peice of code :

https://github.com/MyRobotLab/myrobotlab/blob/develop/src/org/myrobotla…

You will see that it's actually an exponential relationship between speed and velocity, and if you trace through the InMoovArm service code, you'll see it actually maps down to the method that I listed above.

Next, I'm not sure that the current velocity control is actually 100% mathematically correct, as it's implemented at the arduino level, and I am a little concerned that the math didn't look framiliar to me.  (but it might be 100% correct, but generally, when it comes to servos, you control position , not velocity.. so we need to compute the angular velcoity for the servo and resolve that back to an angular position.  This should be done using standard questions such as   x(t) = 1/2 a * t^2 + v * t + x(0)    ...    In general, we're not supporting acceleration, so that term is zero. leaving x(t) to be v * t + x(0)  ...    If we stretch our imagination, we can consider the angular position to conform to this equation assuming a constant velocity (as acceleration is 0.)  

This means, that in order to compute the position that the servo should be at, you need to know how much time has passed since the last time you set the position and also what position it was at when you last told the servo to move.  I think the current arduino code does this, but I'm not so certain that the change in time is actually what's expected...  (I'm pretty sure I left a comment in the code about this at one point.)

There's a lot of history around this topic, and I don't want us to change any of this prior to Manticore release. 

Lastly,  Stuff like this should be implemented in the Java layer, as that's official... if you want to update python scripts locally to do anything you like you should definitely feel free to do that...  As for contributing it back to the InMoov repo, I think that Moz4r should be involved in that conversation also.

 

Sorry if I am being stubborn on this.. but I think that the whole servo speed/velocity stuff has hurt the reputation of MRL and I believe , if  we're going to change it again, we really should think it though much more completely and holistically , rather than just giving people yet another option for it.

 

-Kevin

 

 

 

Hi Kevin

Thanks for your lengthy and great explanation.

I do agree with all your statements however struggle a bit with the change from the old to the new way of controlling the speed/velocity mostly because its a change from a relative setting to an absolute setting.

To use deg/sec as fundament is unquestioned a great improvement and also allows to take individual modifications of the robot into account (e.g. using a more expensive and faster servos for the omoplate).

However, in order e.g. to slow down movements for the arm, we will need to memorize or lookup the maxVelocity values of each of the 4 servos. In case of the current java defaults it is 20 for all 4 servos but using the values of ".../InMoov/config/skeleton_leftArm.config" it is

bicep=26
rotate=18
shoulder=14
omoplate=15

To a gesture creator / adaptor to run a movement at half speed he will have to use:

i01.setArmVelocity("left", 13, 9, 7, 7.5)

So what I wanted to have back is a relative setting versus the absolute setting. Something like

setRelativeArmVelocity("left", 0.5, 0.5, 0.5, 0.8)

I am not requesting a change of the java code. I simply wanted to show a way how I

- replaced all depricated set<xx>Speed lines in the gestures with set<xx>Velocity entries

- maintain a relative setting against an absolut setting (beeing aware that it might not be the exact speed I was used to and might need adjustions in the gesture file anyway sooner or later)