I am a bit annoyed by the recent change that broke the Integrated Movement service. In the past I was always take great care to not break anything that may used shared code. My code was maybe clobbering or misplaced, but was not affecting anything else. Now part of the code I used have been modified or removed and IM service is not working anymore.

What I was doing:

  • when servo are registred in the IM service, it was enabling and registring to listen to ServoEventData. So when a servo change it's position, it report back all the info need by the IM service.
    • Now the ServoEventData class have been rename and data that it was containing changed so it's not anymore what the IM service need.
  • It also set the servo to listen to the published changed to the position asked by the IM service
    • this has been comment out!
  • the IM service set some info grabbed from the servo to the DHLink. This is because the DHLink and DHRobot arm are used not to only compute position, but to compute dynamic (ie in 100ms, the position will be that way considering the usage of the servo
    • those data are if the servo are moving, and where they are going and at wich speed.
    • I see comment that it's not the place for that.But if not, where that can be placed?

I know using ServoControl or any other kind of Control to support any kind of actuator is the way to go. But before going to that, I did want to get things woky and avoid expanding the code need all over the place. By keeping it to only Servo, I could control better and have less impact on the rest of the code until it's ready or need for other control.

 

So how can I fix the IM service the best way considering the data that it need to work ?

 

GroG

5 years 4 months ago

If you want to get unblocked do the following.

Create a new directory

mkdir annoying 

cd annoying

 
cd myrobotlab
 
git checkout 0b6584afa0f631bf80fba4eb4baa0f8d509a3a93
 
git checkout -b integrated_movement
 
copy any new changes you want from your current source to the new directory

Greg

I think you get me wrong.

I am annoyed the the project I was working on is now broken. Who will not?

I am not mad at you or annoyed by the change you did, just annoyed by the fact it's not working anymore.

I do understand what you have implement and see that as a step forward. I don't put that in question. It was just not working for IM in the current state.

What I want to do is to fix IM in a better way, and hopefully in a way that it won't get broken on the next change. But i'm not sure how to do it. There must be a reason you remove some stuff IM need and I'm not sure I understand why. If it's because I did something wrong, I don't want to redo the same mistake.

But yes, doing as you said and keep my code locally will be a much easier solution so I won't had to care about breaking other stuff and will stop bothering you

 

Sorry calamity,

I did misunderstand you.  

As for my reply - please use it, and let me know if that will keep your project working. 
If it does work for you, that would be best.
Because then you can push your solution as a new branch and we then can merge it.
This is the way developers work.   For example, I rarely work on the develop branch - instead i work on my own branch and push changes, and kwatters reviews them and "sometimes" merges them.  You should do the same, eveyone should.  

After your project is working the way you want, we should get JUnit tests for IM (so it won't break again), then you can push it and we'll work together merging it.

Start with the first step which are the git commands I mentioned in my first reply.

Greg

Yes I can work with branch. I was doing that a lot locally, especially when doing a lot of changes or working on different aspect of the code. And i'm fine doing it that way. That's not was is holding me. The review thing is just a good thing to avoid problem.

What make me unsure how to fix it Now the way IM communicate with Servo have been removed or changed and that what broke IM. 

So my question is more about did I implement communication between IM and servo in a bad way, there is a better way to do it? 

At first, Servo where only publishing it's current position. That was not enough for the data hungy IM service so I make it publish the needed data on demand in the form of a data class ServoEventData. But that have been changed probably because it's not defined in the ServoControl.

So how do i can implement the communication between IM and Servo?

 

 

Servo is one of the oldest services, and one which has a lot of problems.   Its currently very difficult to make it better without breaking everything (although that's what happened anyway)

HobbyServo is my replacement for Servo - I'm waiting for kwatters and others to try to use it.  Its better than Servo in many ways

  • It can support encoders
  • TimeEncoder is a new (minimal hardware) "default" type of encoder
  • TimeEncoder is more accurate than data flying back and forth over the serial connection
  • It implementat EncoderControl which "real" encoders can implement .. ie its very pluggable for other encoder types
  • Regular DC motors follow the same pattern

HobbyServos publishMoveTo(ServoControl) ..

im.subscribe("servo01", "publishMoveTo")

then you will get the data in onMoveTo(ServoControl sc) and all the servo data

so on a moveTo control command - listeners can get the whole servo and all/any its data.

That will get you the intention of the move :

 

This will get you the stream of changing data

im.subscribe("servo01", "publishServoData")

onServoData(ServoData)

ServoData has a position, state, and name.
state can be SERVO_START, SERVO_POSITION_UPDATE, SERVO_STOPPED

Low level services like Servo should not know about high level services.  For the most part, the less Services know about each other the better .. then they are like seperate clean blocks to play with  (not covered with gooey glue)

HobbyServo extends from AbstractServo where nearly all of the functions are implemented.
If we need a Servo with different behavior we'd make a class like ServoX and  extend it from Abstract servo, the override the appropriate methods for the new (different) behavior.  

You might be interested in TimeEncoder too - which is not a service .. its just a class, but it calculates the trajectory of HobbyServo - specifically the method calculateTrajectory.

I tested it a bit and it seems to be accurate, although it wouldn't surprise me if there are a few hiding bugs in there.

HobbyServos also work with the new full body inmoov.

Do you need something I missed ?
 

Thanks for the answer, that gives me new possibility to explore. HobbyServo seem to have more things useful for IM

One more thing. IM is commanding Servo by publishing needed position data and Servo where set to listening to that channel. I was suggested in the past to not used directly the servo and do it that way. HobbyServo don't seem to offer that possibility. Should I go back and have IM more directly control the servo thru ServoControl.moveTo(X)? Or do you have a better way to do it?

 

we'll get it all worky again.  I think the idea is that IK / IM service needs to deal with ServoControl now.. not Servo class directly.  If there is something missing on ServoControl interface, we'll add it...  

ik/im services shoudl publish joint angles.. and the servos should continue to listen to those events..  also,.. servos should publish their positions ...  it would seem that the position data isn't enough, and we also need to include the current velocity of the servo..  (This will likely be estimated for hobby servos..)

I haven't reviewed too closely, but I think this shoudl be sufficient. the IK / IM services should program against the ServoControl interface instead.  This gives us hardware independence so we need to do it.  

I know it's painful, but let's work together to get it working again

I really like the publish/subscribe way and wish to continue using that way.

About the servoData, position data is enough for most case. IM need a bit more data because it use the inverse kinetic model to estimate position in time. The goal is to avoid a potential colllision before it happen instead of after it happen. Since the velocity setting can be change at any time by many way (script or gui, etc) I think it is as important to be provide in real time. The velocity (or speed) setting and position data also don't give information about the heading of the servo. IM get that info with the targetPosition. Target position both provide the heading and with the velocity setting, estimate how much time it will move. Maybe the TimeEncoder can provide that information in a diferent way, But in any case, IM will need to have access to that info.

I'm not complaining about the change, I just want to be sure I do thing the right way. Yesterday, I was feeling a bit lost about it.

The HobbyServo publishes its moveTo account with all its information - you get a reference to the ServoControl, and the time you get it - is when a new moveTo command has happened.

This is what the TimeEncoder currently uses to calculate trajectory.

Positional information is published at increments.  It does not contain the whole ServoControl, but it does contain the name of the Servo that sent it. But, I don't suspect you'd need it.  If you do just get it from ServoControl sc = Runtime.getService(servoName)

Make sure you always use ServoControl and not an actual Servo or HobbyServo.

With the move events you can forward predict movements and calculate future collisions.

 

I think it would be worth mentioning sooner than later the benefits of thinking about Digital Twins .

I work with IoT devices and digital twins at work work..   I can say from experience, that many problems arrise when status data gets confused with command data.

And things quickly get very complex if you chain status with control.

Lets keep it simple and think of devices or virtual twins with very simple loops of control messages with status feeding back in a mrl "hub"

 

Not this way with "chaining"

Keep it simple - control flows out of mrl, status flows in. 
If we want to send a control msg to a real device and a duplicate control msg to a virtual twin, it should be easy to do thisIn the past it wasn't.  HobbyServo has another advantage over Servo in that it can have multiple controllers - they may be virtual, or real, or both .. actually as many as you want. 
You could have 3 controllers, one virtual, one real, and one predictive.  If you try chaining these things it turns into a big mess.