Asked — Edited
Resolved Resolved by DJ Sures!

How To Stop A Moving Servo

I'm learning how to use EZB scripts. I'm doing a very simple exercise. I make a servo move , and want it to stop it as soon as a sensor makes a digital input high. I'd want to see how long it takes to actually stop. I use "release" to stop it (it's a digital servo, it will keep its position even with no signal). I see no other script statement to stop a servo movement. I wrote this script:

servospeed(d3,5) servo(d3,180) (the servo travel, from 130 to 180, lasts about 3 sec.) sleep(200) if (getdigital(d11)=1) release(d3) endif

The sensor is activated during servo travel, (3 sec.) but the servo reaches its target, ignoring the "if" statement . What's going on ? stress stress


ARC Pro

Upgrade to ARC Pro

Unleash your robot's full potential with the cutting-edge features and intuitive programming offered by Synthiam ARC Pro.

#9  

ok,DJ. you solved the question. By the way, I always have problems in understanding how to use scripts. I hope that in some new version of ezb there will be a better explanation about each statement, and a better alphabetic or logical order in the list of statements to make it easier to find the one that could help. I have to go up/down each time.

@PTP. Thanks to you, for remembering that EZB firmware, while moving a servo, can't do anything else until it's finished. I'd expect that a rather fast and powerful MCU like that could do something more than merely outputting a PWM ! http://www.ez-obot.com/emicons/emo_biggrin.gif

PRO
USA
#10  

@Leonardo,

I didn't say that, let me explain.

1) Your EZ-Script code runs on ARC and ARC communicates with EZB controller, the communication is one way, e.g. Get Something, Do Something. The EZB can handle multiple tasks, for example while playing music, you can keep sending more commands, while moving a servo you can keep moving other servos etc.

2) Moving a servo without a delay i.e. ServoSpeed (0) is a simple task, ARC sends the action Servo(P1, X) to EZB controller, ARC knows the servo P1 is in position X

3) When moving a servo with a delay e.g. ServoSpeed(10), ARC sends the action Servo(P1, X) to EZB controller and assumes the servo is in position X, but the true is not, EZB controller is slow moving the Servo.

4) Release Release does two things, stops the servo and releases the servo. The reason why i don't like release (DJ pointed that too) when you send the Release you can stop a slow movement but ARC is not aware where the servo is.

5) GetServo(P1) The command does not query the EZB controller servo position, basically returns the last Servo(P1) position. Providing a EZB firmware call to return the real position could help when you Release a servo while EZB is still moving the servo.

5) StopServo(P1) Note: does not exist Stop command could be sent to EZB controller to stop the servo, and EZB controller would return the servo position (not servo feedback), that way ARC would be in sync with EZB

one example:


#full speed
ServoSpeed(23,0)
Servo(23, 1)
Print(GetServo(23))  => servo position is 1 
Sleep(2000)

#slowest speed
ServoSpeed(23,10)
Servo(23, 180)
Print(GetServo(23)) => ARC returns 180, EZB started moving the servo from position 1 to 180
Sleep(1500) 
Print(GetServo(23)) => ARC returns 180, EZB is still moving the Servo
Release(23) 
Print(GetServo(23)) => ARC returns 180, EZB is not moving the servo and the servo's position is not 180.

while EZB is moving the servo ARC is not aware of the servo's real position.

DJ's solution is the only true way to know where you are.

And yes i don't like the Release :-)

The MCU is powerful, but you need to adapt the logic when you are away from the MCU, is like working remotely.

I hope it's clear now, I'm sorry if you got the wrong idea.

#11  

Many thanks, PTP, for your detailed explanation. It'll be a reference for me when trying to write scripts. You helped me to understand how EZB +EZB controller work. It's like the captain of a ship, giving a command : " 5 degrees to right !" . He doesn't know the real position of the rudder helm and when his command will be fully executed. He assumes his command is being executed, and the ship will steer 5 degrees. If you ask him, he couldn't say anymore than this. And nobody knows the real servo position, except its internal pot , that doesn't give this information to anyone outside. Some servos , using serial communication, can give this information. Standard servos can't.

#12  

I can think of one way to use the servo release command and for ARC to know where the servo actually is. Please forgive if this has already been mentioned;

1). First you need to set the start position and speed of each servo you have in your project in the INT script when you start up ARC. (Also set your Min Max settings for your servos in the INT script while you're at it). 2). When you want the servo to start moving send it off in the direction you want it to travel and at the speed you want using whatever command you have been using. 3). When the servo reaches the point at which you want it to stop send the Release command. 4). Now the servo is stopped but ARC does not know where it actually is. Hopefully you know the setpoint (the degree you wanted it to stop at). Use that knowledge to reset the servo's position and speed by sending a new set of servo(), Servospeed() commands like you did in your INT script.

Hopefully this position command will be very close to where you wanted it to stop. You may experience a little additional servo movement while the servo moves back to the last sent command set point (position) because it may have overshot. Now after it moves back to the sent position ARC knows exactly where the servo is.

Not exactly a clean stop but at least you now have a true position for ARC to work from. This would only work if you can tolerate some movement after the release command is sent and time enough to reset the position before you send the servo off on another journey. :)

#13  

Thanks for your answer, Dave. I can't reset the servo after the release command (your point 4), because the servo has no pre-determined position to go to. I don't know where the servo has to go. It stops where a sensor, during the movement, detects and object . After that I can't know the position, using release. So iI prefer the method by DJ, by which I can know with a sufficient precision where the servo is.

#14  

Humm, I understand where you're coming from. I'm at a disadvantage as I don't know how you're using these servos or anything about your project.

However as far as starting the servo's up in a direction you may need to just either set the setpoint at either 1 or 180 and send the release command when it gets to the point you want to stop it. I've not tried that so I don't know if that will work.

As far as knowing where it stopped I guess that's the trick here. I assume it is stopped at a random place each time? The only electronic way In know would be to somehow attach a pot to the project somewhere and read it with a ADC port.

#15  

Okay, my 2 cents.

Would it be possible to put a switch in the system such that it would close at the point where the servo has reached it's maximum travel? This is so a signal can be sent back to an ADC input. Using a script generated counter and this switch you could calibrate the servo such that you would know where it stopped pretty closely.

First you would run the servo all the way to the starting point, perhaps 1 degree. Set the servo at the speed you want it to go during normal operation using the ServoSpeed instruction. Then a calibration cycle takes place. You would start the servo and a counter at the same time. When the switch closes, you stop the counter and remember the count. You now have a relationship between the counter's count and the servo position. If you want more accuracy, you could run the cycle 3 times and average the result.

You then start the counter again each time you run the servo. You stop the counter when you stop the servo. Knowing the count, you now have a fairly close estimate of the degrees moved. This allows you to get a bearing on where the servo is when stopped.

For example, Let's say, during the calibration cycle, the servo moves from 1 degree to 100 degrees, and the counter counts 10,000 during that time. We then have a relationship of 10,000 count /100 degrees moved =100 counts per degree. So, during normal operation, let's say the servo moved such that the counter has counted to 5000 (for example) when it is stopped by the release command. The degrees moved would be: 5000 count/100 counts per degree =50 degrees. When it's time to move the servo from where it is, the command Servo(Dnn, 50) is sent out first. It should already be at 50 degrees so little, if any, movement should come from the servo. Once the servo command for 50 degrees is sent out, the system then also knows where the servo is.

It may be possible to do the calibration cycle without a switch by watching the servo and clicking a script button manually when you see it it reach it's maximum travel (when it stops) . Again, you could do this several times and take an average of the counts for greater accuracy. A switch, however, would make the whole operation automatic. That would allow the initialization cycle to run a calibration script first thing when the robot connects. However, that may not be necessary since the count vs time relationship is not likely to change from run to run. Done once, it could be entered into a script manually.

Of course certain assumptions are made here.

  1. The servo has very little load on it, so it moves freely at any speed.
  2. The servo's rate of movement isn't going to physically change much as voltage decreases with use during a given run. If it does, the voltage can be monitored and either an adjustment factor can be introduced every X-Number of volts (or fraction of a volt) drop, or the calibration cycle can be automatically re-run at those lesser voltage points (assuming a switch is in place).

I can write a script to do all this if you like. It won't take long. Though it may not seem like it, such a script should be pretty simple to implement.

#16  

Hi, Dave. I'm experimenting a robotic arm searching for an object on the table and then grasping it in its hand. No need for extra pots. The pots are in the servos ! The arm is first positioned at 2 inches above the table, then moved around ,by a script, from 130 to 180 degrees, to detect the object in front of the hand, by IR sensors. When the object is detected, the arm is stopped , the hand is moved towards the object, stopped ad the right distance, then closed. To stop the servos, I had good results using DJ's method, i.e. commanding, by a loop, small step-by-step movements (e.g. 2 degrees) , then polling each time the IR sensor, and halting the script when the sensor detects the object. This way, the position is known with a tolerance of 2 degrees or , if wanted, even 1 degree. Simple, but effective. Hi,wbs00001 I appreciate the idea you suggested, i.e. tracking servo movements by a calibrated counter . I already had good results using DJ's very simple method (described in this post) consisting in only 4-5 lines of code. But, if you want, write the script for your method for me to see an alternative way.