Query Movement Status Trouble

Hi,
I would like to perform a cyclic movement as a sequence of steps so I program
the following code (I know this could be done with a single instruction but I need
to use a sequence…) :

while ( true )
{
if ( pos == 2200 )
step = -100 ;
else if ( pos == 800 )
step = 200
pos = pos + step ;
codifyRefPulseSpeed( seq ) ;
sendRS232( seq, size ) ;

//this is the important part
do {
    usleep( foraWhile ) ;
    sendRS232( "Q\r", 2 ) ;
    receiveRS232( status, 1 ) ;
} while ( status != '.' ) ;

}

Well the cyclic movement is performed but the delay between two steps may vary between 0 to half a second.
The QMS instruction is supposed to answer within a delay of 50uS to 5mS; but it fails.
If you do not use the QMS instructions, positions’ commands saturate the buffer and very few are performed.
A solution could be to compute the necessary time for the SCC to perform the current step before sending the next one.
Does anyone knows an easiest way ?

Thanks in advance :mrgreen: .

looks like you may have an uncontrolled loop running in your code, which may have your cpu pegged at 100% making for a delayed response.

“looks like you may have an uncontrolled loop running in your code, which may have your cpu pegged at 100% making for a delayed response.”

Thanks Zoomkat, but I don’t think so, at each cycle I send a command and wait for its completion;
to avoid saturating the cpu I use a “sleep” in the " sendRS232( “Q\r”, 2 ) ; receiveRS232( status, 1 ) ;" cycle
I’m afraid that the “Q\r” is much slower than specified or the input buffer smaller…

Nope… This function is well established in many applications. There is no inaccuracy of the delays listed in the docs. I don’t think the input buffer has any impact on the Query command. I know this is not helpful, but if there were a problem with the Query command it would surely have been fleshed out by now. Please provide a more complete code example.

Sorry, but I don’t know which platform you are using or the like. It obviously looks like C, but not sure which one, so not sure about timing that way… Likewise you are not mentioning anything about what types of commands you are running or the like.

In the phoenix code (hexapod), it used to also try the Q command to do things, but yes there can be a delay. I don’t think I ever saw anything near a half second. In the phoenix code we output the moves to complete in a certain amount of time “T” portion of the servo move or group move(lynxmotion.com/images/html/b … htm#srvmov). So our code knows how long the command is supposed to take and we wait that amount of time before issuing the next one.

Good Luck
Kurt

The code seems to be fine as it works when the given delay (sleep) is sufficiently large to ensure a periodic movement
but with a shorter delay required by real time a similar action may be performed in very different timing. For example, if you display a '’ when requiring the movement and a ‘.’ in the query cycle waiting for completion, you got something like
. meaning that the delays to perform a similar move on one servo may vary from 1 to 7 times ! That’s why I think the “Q\r” is to blame…

Hi Kurt, all is programmed in C++ under Linux and compiled with Gcc; we have built several robots including one with 27 servos whose control appears to be satisfactory. Nevertheless (see the previous answer to Jim) I can’t explain why real time responses are so different (roughly factor 7). For example, if you want to build an inverted pendulum, you need your commands to respect a precise timing; we fail in that attempt…

As I mentioned, the phoenix code does it’s own timing.

That is the code issues a command, knowing how long the move is supposed to take, it does what is necessary to setup the next command, it calculates how much time the setup code took, subtract that from the time of the last command, wait that amount of time, and issue the next command… Sometimes you need to a little fudge to know how long it will take you to issue the next command and use that in your code estimate. In some versions of the phoenix code, I had the code output all of the next command up to the terminator (CR for ASCIIs, Time stuff for binary version). So all you have to output when the time is right is either 1 or 3 bytes…

Works well in the phoenix code.

Kurt

You are suggesting that the Q command is not working correctly. Which of the following do you suspect?

  1. The SSC32 sometimes takes much longer than 5ms to respond to the Q command.
  2. The SSC32 sometimes continues to return ‘+’ even after the move is complete.
  3. Something else.

It would be helpful to know some additional detail. Specifically

  • What is the move time and/or speed in the command sent to the SSC32? (And is it always the same?)
  • What is the sleep interval in the “usleep( foraWhile ) ;” statement?
  • Does the statement “receiveRS232( status, 1 ) ;” pend/spin until a byte is received, or does it return immediately? (I assume it pends, but it is always good to ask.)

As always, visibility into the code is valuable. If you have a way to monitor the serial data stream to/from the SSC32, that would be ideal. Then you can see exactly what is going on. The next best thing would be to instrument the code to send info the debug console. Look at the servo move command to make sure it is what you expect, and print the SSC32’s response to each Q command.

Mike

@jlp Mike designed the SSC-32 and wrote the firmware. If there’s anything wrong he will be able to help you figure it out. :wink:

That is probably the best thing to do. Querrying the movement command status is just adding useless churn to your setup. You already know the value you are going to use for the servo position. Remember that the ssc-32 knows nothing about the actual position of a connected servo.

Isnt it just to measure the the Voltage on the middle soilderpoint in the potentiometer on the servo in question ?

No, the “Q” command only checks to see if the ssc-32 has finished sending its commands to the servo.

I thing you misunderstood … or i didnt explain enough

If you carefully take the servo apart, solder a wire to the middle of the three solderpoints , i think its called “the brush”, and then put the servo together again. Now you have a absolute feedback exactly where the servoposition is, if you can decode it, and its quite simple: You just move the servo to one end, for example 500us, save the voltage, then move it to 1500us and save the voltage. Now if you have a reading of for example 3,26V you can easely calculatre the exact position where (in us) the servo is

hrmmm… was this explanation understandebal ?

Please observe, i have NOT done this IRL, but if you have spare analoge inputports it souldnt be a problem … i think …

Not the same.

Yes you can read the wiper of the pot, and calculate its position, but that has nothing to do with the Q command. The Q command will respond with + when the command has executed.

To use the voltage read from the R/C servo pot in a positioning system, you are essentially creating a ‘P’ (proportional) controller (simple closed loop).

Alan KM6VV

you are right

Been there, done that.

viewtopic.php?f=2&t=2748
viewtopic.php?f=31&t=3182

I just thoght it was an easy answer to jlp initial question, whithout solving the initial cause of the problem… because it was certanly way over my head…

@zoomkat
it was a very nice “Proof Of Concept”, did you use it for anything after that ?

No, I just did it to see how it could be done. It is more practical to query the last position sent to the servo when some event happens. Below is a test of that idea.

viewtopic.php?f=8&t=4658

The C++ code in attachment shows the trouble with the Query Movement Status :
If you compile the code as given (adding main and rs232 subroutines) you should find
the servo from time to time freezes for half a second. Now, if you comment the query
cycle, the servo performs at a higher rate and never freezes.

I am still not sure where the problem came from; eventually a cause may be our own
RS232 send/receive methods…
checkServo.cpp (2.25 KB)