OpenServo.com Forum Index OpenServo.com
Discussion of the OpenServo project
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

V3 Experimental Branch
Goto page Previous  1, 2, 3  Next
 
Post new topic   Reply to topic    OpenServo.com Forum Index -> Software
View previous topic :: View next topic  
Author Message
kbb



Joined: 01 Jun 2007
Posts: 180

PostPosted: Sun Aug 01, 2010 3:12 pm    Post subject: Reply with quote

jharvey wrote:
<snip> setvelocity(0x8000) <snip>

The experimental firmware has velocity control. The value set is treated as a signed intreger; but there is no direction control implemented. 0x8000 is a large negative number. Therefore the firmware will hold position. Try a value like 4.

The valid range is 0 (no movement) to 0x7fff (the servo will be physically incapable of attaining that speed).

Ignoring issues related to loading, spin-up, timer settings and so on; the firmware as presented will be attempting to drive the servo with a velocity of ~100 encoder/pot increments per second. For example: an unloaded OpenEncoder based servo will nominally complete one revolution in ~10 seconds if the velocity is set to 4. (NOTE: Of course, without direction control you cannot tell it to move from 0 to 4095 in one command to get a full rotation - it will take the shortest path).

jharvey wrote:
<snip> setpgain(600), setigain(0), setdgain(0) <snip>

The firmware has changed significantly: I would suggest trying

setpgain(410), setigain(4), setdgain(290)

A dead-band setting of 1 will probably be better than 0.
Back to top
View user's profile Send private message
jharvey
co-admin


Joined: 15 Mar 2009
Posts: 350
Location: Maine USA

PostPosted: Mon Aug 02, 2010 1:57 am    Post subject: Reply with quote

Well, it now moves very nicely. I bumped your suggest velocity from 4 to 0x32, and it now moves at or near the servos max speed. My move script doesn't seem to work with it quite right. The script can't go full rotation. For the moment, I want to figure out better values for this servo, so I limited my script to 120 degrees. That's a current limit of the script before it starts to keep track of full rotation.

On my MG995 I get a bit of overshoot with the P setting at 410 and velocity of 32. From here, http://en.wikipedia.org/wiki/PID_controller down around the the Ziegler–Nichols method, I set I and D to 0 and get Ku at about 0x10ff and a Pu of approximately 3 oscillations per second for a period of .333. This 10ff seems about right to me, because a P only control like we had, was using a value of about 500 to 600, which is a bit below the .5 setting of 87F. So the first line of this table appears to be close to what we experienced in the real word. Which is a good start.

Therefore, I calculate the third row as Kp=.6Ku=.6(10FF)=A32, Ki=2Kp/Pu=(2(A32))/.333=3D2C, and Kd=KpPu/8=A32(.333)/8=6C. However, this oscillates. Perhaps caused by system noise, or perhaps the calc's aren't a pure I or D calc's. I don't know why it was oscillating, we must be near a hole or pole. It didn't seem to help much by changing values slightly, so what ever the reason for a hole or pole, it's not a small one.

So I try the manual approach, and I get these results. Kp=200, Ki=50, Kd=ffff. These settings hit their mark in a fraction of a second, it overshoots just slightly, and settles after one or two misses. The system seems stable both loaded and unloaded. Also more inertia decreases the overshoot. I also tried setting Kp to 50 and Ki to 200 simulating the 6X ratio noted in the third row of the table. This did seem to work well, but oscillated a bit, so I didn't go with those results. It seemed unstable-ish.

I've been running the move script with these parameters for about 10 minutes, and I haven't had to touch the little arm yet. I really like having this I term, which is making for a much better steady state error correction. I don't currently know what the dead band is set to, probably 0. I'll have to figure out how to set that in the near future.

The next step is to look closer at getting my script to support a full 720 degree command.
Back to top
View user's profile Send private message Visit poster's website
kbb



Joined: 01 Jun 2007
Posts: 180

PostPosted: Mon Aug 02, 2010 7:58 pm    Post subject: Reply with quote

jharvey wrote:
On my MG995 I get a bit of overshoot with the P setting at 410 and velocity of 32.
<snip>
However, this oscillates. Perhaps caused by system noise, or perhaps the calc's aren't a pure I or D calc's. I don't know why it was oscillating, we must be near a hole or pole.

That is one of the “things needed” that I alluded to. One (probably real big) reason for the overshoot is that the PID calculation does not “know” directly about the inertia in the system, and I suspect that you probably cannot “tune it out”. That is, the PID to PWM function does not turn the power to the motor off until it is called when the servo position is at or past the set seek-position; inertia does the rest. That is one reason for the oscillations: once it has over-shot the target PID tries to snatch it back the other way. That explanation is probably not as clear as it should be; but you get my drift.

One solution to that problem is to build in a “model” that will help “predict” the overshoot or when to turn the motor off and coast. However, that is more complex that it might appear at first (experiments some time ago showed that it depends on the load and velocity, even the orientation in relation to gravity). Hence my belief in the need for a built in model rather than a fixed interval. I imagine the measured power (VA), current estimated velocity and so on may all play their role here. I haven't had time to work on it much.

I also suspect that at the very least it really needs two separate sets of PID parameters: one for “travelling” and one for “holding position”.

Your large gain values probably cause the 3Hz oscillations; but without proving much improvement (other than maybe drive the motor faster if that is what you intend)?
Back to top
View user's profile Send private message
jharvey
co-admin


Joined: 15 Mar 2009
Posts: 350
Location: Maine USA

PostPosted: Mon Aug 02, 2010 8:52 pm    Post subject: Reply with quote

I haven't gotten to look at it all that closly yet, so pardon my ignorance on this item. How do you go from say 359 to 361 degree rotation? I plan to do some tests to see if it will simply roll over when I'm at 359 and I command it to 1 degree. I think it will roll back. Any pointers before I jump into the scripts?
Back to top
View user's profile Send private message Visit poster's website
kbb



Joined: 01 Jun 2007
Posts: 180

PostPosted: Mon Aug 02, 2010 9:41 pm    Post subject: Reply with quote

jharvey wrote:
I haven't gotten to look at it all that closly yet, so pardon my ignorance on this item. How do you go from say 359 to 361 degree rotation? I plan to do some tests to see if it will simply roll over when I'm at 359 and I command it to 1 degree. I think it will roll back. Any pointers before I jump into the scripts?

If you have uploaded the “full rotation” version of the firmware, then once it reaches “4084” or thereabouts, you tell it to go to “12”; it should take the shortest route. So yes, it should rollover! If you want to convert degrees to OpenEncoder position the conversion factor is 11.3777... For example: seek position = (degrees*11.37777) modulo 4096.

One would want to add an option to the firmware to allow seek positions/velocities to be in 100ths of a degree (being as it set as an integer). It is another thing on the list. Three issues come to mind. 1: For non-encoder use the relationship isn’t there as such; it would have to be calibrated for. 2: There would still be some kind of rotational offset, that is 0 on different servos is likely to be in slightly, or even totally, different places relative to the servo case; it could be calibrated for of course. 3: There is always the issue about how linear the encoders are; again, this can be calibrated for.

Additionally, I still think it would be better to be able to specify the direction when full rotation is enabled- rather than having to second guess what is going to happen in a script. I am not currently using full rotation myself, other than on the recently constructed OpenEncoder based test servo; but if I get a chance I will add that in, as it should be straightforward.
Back to top
View user's profile Send private message
jharvey
co-admin


Joined: 15 Mar 2009
Posts: 350
Location: Maine USA

PostPosted: Tue Aug 03, 2010 9:51 am    Post subject: Reply with quote

Have you had a chance to test the full rotation? I've programmed it with the oefr firmware, but when I tell it to got from 4084 to 4221 it hangs at 4096ish. If I tell it to go to 12, it rolls back not following the shortest path. I haven't been able to get it to cross that 360 barrier yet.
Back to top
View user's profile Send private message Visit poster's website
kbb



Joined: 01 Jun 2007
Posts: 180

PostPosted: Tue Aug 03, 2010 10:12 pm    Post subject: Reply with quote

jharvey wrote:
Have you had a chance to test the full rotation? I've programmed it with the oefr firmware, but when I tell it to got from 4084 to 4221 it hangs at 4096ish. If I tell it to go to 12, it rolls back not following the shortest path. I haven't been able to get it to cross that 360 barrier yet.

I don't have a test regime for full rotation yet. Yes, you are correct; it does not always take the shortest path! Maybe this was the original behaviour (there were no intentional changes to that part of the code)?

Options to fix this include:

1: Update the code to ensure that for full rotation the shortest path is always taken.
2: Direction is specified by using negative/positive velocity.
3: Either of the above as a compile time option.

Trying to move to 4221 will stop at 4095 because that the limits are deliberately coded in: valid seek positions are 0 to 4095 for OpenEncoder with full rotation enabled. I do not think this is a problem to be fixed. Is it?
Back to top
View user's profile Send private message
jharvey
co-admin


Joined: 15 Mar 2009
Posts: 350
Location: Maine USA

PostPosted: Wed Aug 04, 2010 1:12 am    Post subject: Reply with quote

I believe the original behavior was shortest path, or nearly shortest path. The moveto script chops the move command into a min of 120 decrees per I2C command. Such that if you command it for more than 120, it will rotate 120, then the next 120, ect until the command is less than 120. One issue is that when commanded for these 120 increments, it has to settle on 120, then it moves to the next 120. This causes the pauses noted on the video I posted a while back.

I'm a bit ignorant on this, but I believe the script I have would send 4221 which would get truncated and would actually read as something like 12. I believe the setposition would simply send the first then second bytes, so perhaps it was truncating at 16 bits instead of 12 bits. I'm not certain. I think this truncating is happening in the firmware, instead of the script. Heres the snippet of the set position command.
Code:
return self.write(_REG_SEEK_POSITION_HI, [position / 256, position % 256])

I'm still learning the nitty gritty on this, and I'm short on time, so it's been baby steps. Thanks for the help. I believe the above /256 is very similar to shifting 8 bits. The remainder is dropped and the top bits are sent over I2C. The %256 is also shifting by 8, but only includes the lower 8 bits, which are then sent via I2C. I guess I'm a bit more used to doing this like this <<8 && 0xff for bit shift 8, then mask. However, I think both are valid approaches.

I guess the next step is to look into the firmware a bit closer. To me it looks like I know fairly well how and what is being sent over the I2C, so I guess it's time to see how it reacts to those commands. While I'm looking it over, I'll get a chance to see how you implemented I and D.
Back to top
View user's profile Send private message Visit poster's website
kbb



Joined: 01 Jun 2007
Posts: 180

PostPosted: Wed Aug 04, 2010 8:36 pm    Post subject: Reply with quote

The “problem” is probably two fold: firstly the experimental firmware internally limits any seek position sent to the physical bounds of the hardware. That is, if you send 4221, then it will stop at 4095 with the OpenEncoder. The old firmware only implemented the restrictions you might set for “seek minimum” and “seek maximum”. If they were set appropriately, 4221 would be allowed and “work”. Secondly I assumed one would want to set the position specifically (and eventually set direction too) and it did not occur to me that anyone would be using an “excess hack” to control it - so the excess hack is broken in another way too! All fixable of course.

jharvey wrote:
I believe the original behavior was shortest path, or nearly shortest path. The moveto script chops the move command into a min of 120 decrees per I2C command. Such that if you command it for more than 120, it will rotate 120, then the next 120, ect until the command is less than 120. One issue is that when commanded for these 120 increments, it has to settle on 120, then it moves to the next 120. This causes the pauses noted on the video I posted a while back.


Yeah; that is one reason why I am suggesting that move to position X in a given direction is better than using the “excess hack”.

So my offer above still stands, except we could now add back the “classic” mode:

Method 1: Direction is specified using negative/positive velocity.
Method 2: Update the code to ensure that for full rotation the shortest path is always taken.
Method 3: Old behaviour (includes: excess is dealt with and anything else that can be identified). Might be the same as 2, but with a different min/max.
Method 4: Any one of the above as a compile time option.

Obviously the smaller the number of options, the less the amount of testing needed when making changes, although I suspect 2 and 3 can be implemented via 1 so maybe not so bad. I will probably implement method 1 as it seems like the ideal method to me. With the others you still need to “manage” travel from outside.

I wonder if anyone wants a “continuous motion” option?

jharvey wrote:
I'm a bit ignorant on this, but I believe the script I have would send 4221 which would get truncated and would actually read as something like 12. I believe the setposition would simply send the first then second bytes, so perhaps it was truncating at 16 bits instead of 12 bits. I'm not certain. I think this truncating is happening in the firmware, instead of the script. Heres the snippet of the set position command.


Hard to say without seeing all the bits and bobs.

jharvey wrote:
Code:
return self.write(_REG_SEEK_POSITION_HI, [position / 256, position % 256])

I'm still learning the nitty gritty on this, and I'm short on time, so it's been baby steps. Thanks for the help. I believe the above /256 is very similar to shifting 8 bits. The remainder is dropped and the top bits are sent over I2C. The %256 is also shifting by 8, but only includes the lower 8 bits, which are then sent via I2C. I guess I'm a bit more used to doing this like this <<8 && 0xff for bit shift 8, then mask. However, I think both are valid approaches.

Assuming all the data types and the input value workout as appropriate integers and so on (which I imagine must be the case if it is working) “/256” is the same as shifting down by 8 bits, “%256” is modulo 256, which is the same as “&0xFF”. As it works, we can say that that code is converting a number into its two component byte values.
Back to top
View user's profile Send private message
jharvey
co-admin


Joined: 15 Mar 2009
Posts: 350
Location: Maine USA

PostPosted: Thu Aug 05, 2010 12:08 am    Post subject: Reply with quote

kbb wrote:
Method 1: Direction is specified using negative/positive velocity.
Method 2: Update the code to ensure that for full rotation the shortest path is always taken.
Method 3: Old behaviour (includes: excess is dealt with and anything else that can be identified). Might be the same as 2, but with a different min/max.
Method 4: Any one of the above as a compile time option.

I agree that method 1 is best, and if it's easy enough, why not also include 2,3. I already have the old firmware, and it works but with out the I,D terms. So I guess it would be nice to have that functionality, but eh, it's also probably best to make it right. Perhaps 4096 or 0X8000 or something similar could set it to continuous rotation mode. I could see where this mode would be handy on a long traverse command. That would reduce processing requirements and I2C noise while on a big move.

How hard would it be to implement method 1?
Back to top
View user's profile Send private message Visit poster's website
kbb



Joined: 01 Jun 2007
Posts: 180

PostPosted: Tue Aug 10, 2010 10:29 pm    Post subject: Reply with quote

jharvey wrote:
I already have the old firmware, and it works but with out the I,D terms. So I guess it would be nice to have that functionality, but eh, it's also probably best to make it right.

The old firmware certainly makes the motor go round; but its motion control seems "not ideal" with the more powerful servos and there is no velocity control. YMMV!

jharvey wrote:
How hard would it be to implement method 1?

I will try to get them done this weekend.
Back to top
View user's profile Send private message
jharvey
co-admin


Joined: 15 Mar 2009
Posts: 350
Location: Maine USA

PostPosted: Tue Aug 10, 2010 11:36 pm    Post subject: Reply with quote

Awesome, I'll look forward to hearing about how it goes.
Back to top
View user's profile Send private message Visit poster's website
nighteagle



Joined: 29 Aug 2010
Posts: 6

PostPosted: Sun Aug 29, 2010 10:51 pm    Post subject: Reply with quote

Hi,

is a litte bit confuse to find the right infomation about the firmware with PID from kbb.
The version *pot.hex from the cvs in AVR_OpenServo_V3-experimental section have i flashed with osif.
But i can't find the i2c device with osif.

Then i flashed back with an AVR-Flasher to the version V3 openservo.hex and all functions true and the osif find the openservo on adress 0x10.

I need the PD + I firmware from kbb can anybody help me to find the right hex-file?


nighteagle
Back to top
View user's profile Send private message
kbb



Joined: 01 Jun 2007
Posts: 180

PostPosted: Mon Aug 30, 2010 8:46 pm    Post subject: Reply with quote

nighteagle wrote:
Hi,

is a litte bit confuse to find the right infomation about the firmware with PID from kbb.
The version *pot.hex from the cvs in AVR_OpenServo_V3-experimental section have i flashed with osif.
But i can't find the i2c device with osif.

What software are you using to look for it? And did you cycle the power on it after flashing?

nighteagle wrote:
Then i flashed back with an AVR-Flasher to the version V3 openservo.hex and all functions true and the osif find the openservo on adress 0x10.


Which ATmega168_OpenServo.hex did you use? Did you try using the “AVR-Flasher” instead of OSIF?

Note that if you are using one of the .HEX files from “AVR_OpenServo_V3” or “AVR_OpenServo_V3-dev”, then it could be that you need to use the “ATmega168_OpenServo_V3-pot_twichk.hex” file from “experimental”, as I think the others are built with TWI checking enabled.

nighteagle wrote:
I need the PD + I firmware from kbb can anybody help me to find the right hex-file?

There is only the one set, in CVS. Because I had to update the code that had OpenEncoder support, I had to modify the code from “AVR_OpenServo_V3”, not the code from “AVR_OpenServo_V3-dev”. There are some differences between the two that are more than just “added functionality” (for example, reported version). Therefore software that specifically expects the “-dev” firmware will not necessarily recognise the “non-dev” or “experimental” firmwares. Various versions of “openservointerface” appear to be one such example.

I haven’t had time to change and test the PID for the “-dev” firmware, which also does not include the “OpenEncoder” support.
Back to top
View user's profile Send private message
nighteagle



Joined: 29 Aug 2010
Posts: 6

PostPosted: Mon Aug 30, 2010 9:54 pm    Post subject: Reply with quote

Yes i cycle the power on after flashing.
To you questions... i use the osif to flash in I2C-Mode and then i use the AVR-Flasher, because i can't connected with the device after cycle power on.


I use an AVR-Progger to flashed this hex:
/OpenServo/AVR_OpenServo_V3/ATmega168_OpenServo.hex

With this firmware all goes true. But this version haven't had the "I" paramater!?!?

So i'm looking for the version with fully PID-Parameters.
Which ist the right hex-file?
I use a standard Hitec-Servo with an poti.

Have i to use this version?:
ATmega168_OpenServo_V3-pot_twichk.hex

Can i set the velocity so that the servo with PWM-RC-Mode use this velocity?
I set the parameters with osif in I2C and use the "save-button" to save it in eeprom.. i read the paramters to verify and all seems okay.
But the servo use the max. velocity in RC_Mode..
What the problem?

What are the right registers for the right Hex-File.. is very confuse in the wiki... Smile)

Thanks for help a stuppid german Smile)

Today i flashed the file:
/OpenServo/AVR_OpenServo_V3-experimental/ATmega168_OpenServo_V3-pot_twichk.hex

i became an usb-error after page 80
usb_os_find_devices .......xxxxxx.....many numbers and adresses an on bus 0

Whats that????

Ohh.. i thik i need to flash the bootloader first? right?
Where is the hex-file of the bootloader?
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    OpenServo.com Forum Index -> Software All times are GMT
Goto page Previous  1, 2, 3  Next
Page 2 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group