OK, since no one has any suggestons about actually changing the PID settings from the tracker.pid tab, or specifics on how to do it with the 1.0.2000 build via a Python script I've tabled getting tracking working with the latest build for now and will do some tests with the older versions of MRL that Gael mentions for InMoov and tracking or at least as close as I can get to those verions.

But I have another issue again with 1.0.2000 and setting the min / max values for the servo range.

I have a simple script that creates and starts an arduino service and then creates and starts a single servo service.

I set the pin for the servo on that servo service, and setMinMax(20, 170) setRest(90) and then attach('arduino1', pin number) and I can move the servo just fine, but min and max show 0, and 180 in the UI. 

For good measure I slow the velocity using setVelocity() and that works too.  I can use moveTo() to move the servo.  And finally the rest() method takes me back to 90..

I use getMin() and getMax() to get the Min/Max values and they are still 0 and 180 respectively.


Edit: 4/3/17 7:53PM ET. - I just noticed that in the WebGUI that the servo service there shows the 20, 170 min/max value that I set with setMinMax, but the UI for MRL does NOT so that may be part of the confusion.  Also, in the WebUI as in the stand alone MRL UI the slider still goes from 0 to 180.  So looking at the source code for tracker.java I see that the setMinMax() method makes a call to the mapper() method.  So does that mean that internally the new limit for Min/Max has been "mapped" to the 0 - 180 representation?  I'll run some tests on a non-critical servo to verify.  If that is the case then there appears to be some confusion between the WebUI reporting the values set with setMinMax() and what the getMin and getMax methods are returning in the script.

Edit2: 8:12 PM ET - Tried a test in the script after setting min/max but the servo appears to ignore the change and moves its full rotation from 0 - 180 no matter what min/max I'm setting.  So then I just started an arduino service and a servo service from the runtime tab.  Noted the 0, 90 and 180 position on the servo by using the slider in the UI.  Then I change min to 20 and max to 100 clicked update.  The UI continued to show my new values.  Ran the slider from 90 to 180 and the servo moved to the 180 position.  Then moved the slider to 0 and the servo went to the 0 position.  I believe that the servo should have only moved to the physical 100 position and physical 20 position, so unless I'm missing something which is likely it looks like Min/Max setting is either not being properly mapped or is being ignored.  Is there something I'm missing here?

So what am I missing as far as actually getting the min/max values to set for a servo.  This is critical especially for the jaw servo in the InMoov head as you need to restrict the motion to prevent accidentally breaking parts.

What am I missing for setting the Min/Max for the Servo service?  Is this a bug in the 1.0.2000 version, or a case of documentation that I haven't found, or hasn't caught up with recent code changes?




6 years 8 months ago

OK, after more digging, and dropping back to 1.0.1723 which Gael had listed was working well with InMoov I figured out my issue with setMinMax().

I was missing a map() call.  When I had tried it previously I had tried map() by itself thinking that it would be mapping the new min/max which it does, but apparantly ONLY if setMinMax is called with the same new values before calling map().  And conversely calling setMinMax() doesn't appear to do anything as far as preventing the servo actually not moving below or above the new min / max values set with the setMinMax() call.

By calling setMinMax(40,101) (Gael's values for the jaw servo)

and then calling map(0,180,40,101) I get the expected behavior in that if you set the servo to 180 it actually only moves to 101 or if you set 0 it only moves to 40.

Tomorrow I'll test tracking with 1723 to see if I have any better success and perhaps settint the PID values will work for me in 1723.  Or maybe if I dissect Gael's InMoov script and InMoov services maybe there will be a clue there for my PID issues.



6 years 8 months ago

hello burtbick

The servo have an input range value (the position you give) and an output range value (the signal send to to servo). The Mapper is doing the conversion between the input value and the output value. By default, the mapper is set to (0,180, 0,180) so the input range of 0-180 is map to the output range of 0-180. (wich is no change).

when you use setMinMax, it set the min/max OUTPUT range but did not change the input range. If you use setMinMax(20,100) the Mapper will become (0,180,  20,100).

There was a lot of confusion about the usage of the mapper and a lot of mismatch  have been include into the code about servo input value and output value. I think the tracker was a victim of that and that is also showing in the difference of the two GUI (Swing and Web).

I think the representation of the SwingGui is correct, when you setMinMax(20,100) the input is still 0-180 and that what the slider is showing, but the servo should move between 20-100.

If you want to also change the min/max Input, use directly the map method




My confusion level was rising, between the different versions of MRL, and trying to test things out

Just trying to get things sorted out.  In the older version that Gael says works well with InMoov I can do map(0,180, 70,160) and setMinMax(70,160) and that gives 70,160 for getMin and getMax.  But 2000 build doesn't!!! But 2000 build works as you say in that I can do map(70,160, 70, 160) and then get the expected Min / Max.  But that is, of course, different than mapping the 70 - 160 limits to an input range of 0 - 180:)

Now if I could just get tracking to actually work I would be quite happy.  I have another topic asking about setting the PID values in the latest build.  I haven't found a real way to do it though the UI.  I have been able to set it using Python scripting based on some code from the InMoov scripts, but then I wonder if that is still valid for MRL 2000? 

The think I'm not clear on is that in the sample script that I was given earlier I have a tracker.pid tab and that shows the value for one PID setting only, but in the Swing GUI if I look at the routes I don't see anything coming out of the tracker.pid service. 

Since I don't seem to see much if any change in behavior when changing the PID value(s) I'm wondering if there is something missing that should connect the tracker.pid output into the chain?

Any suggestions on how to tame the tracker the last little bit?

I would like to do something simple like I have seen others do on YouTube with having a couple of objects on the floor or on a chair, select one of the objects, and then pick up and move the selected object.

In the script I started from after creating and starting the Tracking service I am calling:

tracker.connect(arduinoPort, xPin, yPin, cameraIndex);

What's interesting is that I get












In the filters current list..  That just seems to be wrong, but manually clearing the list and re-adding doesn't change the way things are working.

I haven't had much success getting tracking working with the 1723 version either as there is something that I'm missing that causes a Null pointer and it is NOT clear from the failure what that might be for Tracking on 1723.

So I've come back to 2000 to try and get tracking working again.

Sorry for the long winded description but I'm taking too much time trying to get this working.

Thanks Gain,




6 years 8 months ago

In reply to by burtbick

Hi Burt, 

I don't use the Tracking service and barely openCV, so I can't help you much with that. All I know is that the Tracker service is a bit out of shape and in need of some revision. Sadly, the elves are too few and busy using their magic on other projects.

If you are looking to pick a selected object view by the camera, Tracking service is not what you want. It is design to keep the object centered in the camera so it control 2 servo in that purpose. Having the arm pick up the object required more information than what a single camera can give you. You will need to find the position in a 3D space, not in a 2D space like Tracking service is doing. For that, you need at least a 2nd camera or another sensor to be able to have a 3d coordinate of the object.

I'm currently working on a service (IntegratedMovement) with that in mind. Using the kinect to scan the surrounding and inverse kinematic computation to have the hand reach (or avoid) the objects seen by the kinect. 

Still a work in progress, but slowly going to that goal



I know that the point tracking is supposed to keep the camera centered, and that was what I though would be a fairly straightforward test.  So just trying to get those pieces worked though.

I have cameras installed in both eyes on the head since I knew that when I started to experiment with actually locating and manipulating objects that I would need to resolve in 3D space rather than 2D so I'm especially interested in the IntegratedMovment service that you are working on.

I have a Kinect with power supply that should be here in a couple of days and I was planning on doing some experimenting with that.

But back to the tracking and the erratic behavior that I see.  I would like to understand where the problem is but there is so much development going on that I suspect that things have gotten somewhat out of sync with Tracking depending on what version of MRL is being run.

So I may have to dig into the Tracking Java code and see if I can figure things out from there.

Thanks again,



Hi...i am a new user here. As per my knowledge.The servo have an input range value (the position you give) and an output range value (the signal send to to servo). The Mapper is doing the conversion between the input value and the output value. By default, the mapper is set to (0,180, 0,180) so the input range of 0-180 is map to the output range of 0-180. .when you use setMinMax, it set the min/max OUTPUT range but did not change the input range. If you use setMinMax(20,100) the Mapper will become (0,180,  20,100).


Hello LulaNord


I made a post last week that explain a bit about the servo limits usage and did some modification to it recently


If you use the the latest build (v2017+), setMinMax() will set input and output to the same value, so using setMinMax(20,100) is equivalent of using map(20,100,20,100).

On the previous version, setMinMax was only setting some limits to the output value without modifying the mapper, so using setMinMax(20,100) keep the same default map (0,180,0,180) but will clip any output value outside 20,100 to it's min or max