VICTOR RESPONSE DELAY? - AGAIN

There are a lot of posts on this topic but I have not found a good measurement of the time from when a new PWM value is set in the USER processor until the VICTOR output reflects that change. The closest post I have seen was from Mike Bortfeldt in 2006 that it takes about 50ms for the VICTOR to respond for PWM outputs 1-12. We are using outputs 1 and 2 right now for the right and left CIM drive motors and it seems like it takes over 200ms for the actual motors to respond to a user processor PWM change. We only have indirect evidence in the form of the plots attached which show our failed attempt to get the robot to rotate to a new heading. There are control system enhancements that need to be made to the P and D gains and probably also to remove the clipping at a PWM magnitude of 50 but it also looks like from a system perspective the motors don’t actually respond to the control system changes for about 250ms.

The attached plots show the PWM left and right outputs (before the left side is inverted) and the Gyro reading. This is for our two wheel drive practice bot on a tile floor so the as expected it takes a while to stop it after it gets going and we can fix the code in that area but it also looks after the motor rotation is reversed to slow/stop the robot rotation the angular rate does not even start to change for about 250ms. I would think that the angular rate would start to change very quickly after the motor voltage changes and that makes me think that a lot of the 250ms delay is in the control system. Either in communications between the user and master processor or between the PWM output and the VICTOR output. All I have is this system level data and will not have access to the practice bot until our next Fix-It-Window next Tues. The VICTORS are in coast mode but now that I think of it I’m not sure if they are 883 or 884 - this platform has been around for a few years.

I think the first thing we will try is to move the drive motors to PWM 15 and 16 (camera is on 13 and 14) and we are using the new timer3 PWM code so the outputs should be solid.

From your experiences would you say that this delay is really due to the control system or just physics?

Thanks,

Greg

rotation_response.pdf (40.9 KB)


rotation_response.pdf (40.9 KB)

Greg,
You need to consider that the mechanical system has delay due to the need to get things moving and to stop things that are already in motion. Remember that the gear box is not preloaded so that a finite amount of time is needed just to get all the gear teeth to move to a point where they are touching and can start to perform some work. Additionally, you must begin moving the mass of the armature before you can move the robot. A more valid test would be to monitor the electrical output of the Victor compared to the command. Follow that test with one that tests the mechanical delay and see if those numbers seem a little bit more realistic.

Thanks Al,

I guess I will transition an I/O pin as a timing reference and then monitor the PWM output and VICTOR outputs on other channels to make a measurement. Using PWM 15/16 will remove whatever delay the master processor adds. Other people must have done this as well. When we look at the data I posted we see a period of 250ms where the angular rate remains unchanged after the PWM output is changed and then after the angular rate actually begins to change it takes an additional 175ms or so for the robot to actually stop. But of course when the robot stops the wheels and drive train are spinning furiously in reverse. I figured that even though it would take time for the system to react (including armature speed, gear, chain, and finally the robot chassis momentum) that you would start to see at least the effect of removing the drive voltage right away. But maybe that is not the right way to look at it.

I’m assuming that a four wheel drive robot on carpet will stop faster than the two wheel drive robot on a waxed floor and that will reduce the 175ms part but not have much effect on the 250ms component. If the 250ms component of the stopping time is mostly a characteristic of the motors, gear box, and chain linkage then it should be similar for the real robot and we can use the angular rate to predict when to slam on the breaks. Since it looks like the loop bandwidth needs to be pretty low to accommodate the system lag maybe a binary control approach makes the most sense.

Greg

Greg,
In looking at the data I am guessing the 250 ms is the delay between the transition of the PWM and the first change in the gyro output centered on 3000ms in the top graph? I think we need a little more info. Are you feeding the gyro directly to the RC or are you using a sub processor to interpret data from the gyro? Are you using someone’s code or your own?
I am not a software guy here so I am working from memory on what I think our software team has discussed in the past. Their thought had been to look at several samples from a gyro to determine if the data was in error or that an actual trend was in effect. It was only then that they used the data to effect a change. In reaction to the drive spinning backward while the robot is trying to stop is an indication of fairly high loop gain which also appears in the graph. If you are attempting directional control, I would expect smaller changes in the PWM data. The gyro graph does show some damping but I think it should be even greater which may occur with a lower gain. I would also expect that the PWM values would decrease as the gyro output decreases.
The tougher thing to do is make predictions based on the variables of your drive system, robot weight and wheel friction. Since the wheels are breaking friction with the floor, all bets are off. I would think that speed changes (PWM values) that reduce to near zero (127) would be the most desirable response. In this way you would be getting closer to being on target without stopping forward motion. I would also expect lower magnitude PWM values as you get closer to the target. Does any of this make sense? It was a long day preceded by a short night.
BTW, the view in your photo looks familiar, where in NM was the pic taken?

For what it’s worth, I wouldn’t totally trust the output of the KOP gyro.

See my related thread here:

My experience with the gyro indicated that it has a long time constant of it’s own. I did some basic tests, simply moving the gyro (mounted on a block of wood) by hand and I could see quite a long run-on effect (the gyro was still indicating motion long after the motion had stopped).

With a moderate turn rate (say 90 degrees in a second) the gyro would take a good part of a second to come to a complete stop after the turn had completed. Simulating the gyro with a pot showed none of the same run-on (so it wasn’t a software issue).

This made it almost impossible to control the motors with the gyro in anything except a straight line run (where any turn was only due to variation in the motors/friction etc)

The other annomily was that this latency only appeared at the end of a turn, not the beginning, which makes me think there is some other processing/filtering going on the sensor board itself. Either way it was a mystery I couldn’t resolve.

Yes, the 250ms is about the time it seems to take the measured gyro heading to start to change and the additional 175ms is when the robot stops (or at least the gyro says it stops) and reverses direction. I am basically using Kevin Watson’s adc and gyro code. We are sampling 5 analog inputs, each input each ms (1000Hz) so each channel has a 200Hz sample rate and every two samples are averaged so the effective gyro sample and processing (integration for position is 100Hz) Last year the KOP gyro data sheet said its analog output bandwidth was about 40Hz so I think we are OK sampling at 100Hz. I have not noticed any delay in the gyro output but maybe PhilBot is right. It seems like a good test would be to rotate the gyro into a limit switch and stop and look at the timing of the gyro output along with the digital I/O timing and see if there is significant delay. In this test it took about 2 seconds to rotate 90 degrees or 1571mr (we use mr for angles and cm for distance to make integer math reasonable) so I don’t think we are coming close to saturating the gyro rate output.

It is interesting you mention it because we were looking at the Get_Gyro_Rate() numbers last night and they were bouncing around quite a bit. The gyro angle - what I plotted is nothing more than the integrated rate outputs (100 times per second) so sampling the angle every 26.2ms is kind of like averaging 2.6 rate readings which are already the average of 2 A/D readings. To get the rate we actually take the difference between the previous and present angle because it gives us better results. Besides we are trying to use the same approach to rotate the robot to a target or between two targets and when the camera is giving us angle info we only have the heading to the target. - In summary, from what we have seen Kevin’s gyro code with 200Hz sampling and two sample averaging along with the KOP gyro is good with the angle output.

What you are seeing is our first attempt to try to use the angular rate as a D term and to only finish a turn when the gyro angle was within a 1 degree tolerance and the angular rate was small. Previously we just had a P loop with an error input of mr and a gain of 1/8 or some other power of 2 and simply declared the rotation complete when the gyro angle fell within the tolerance window. So for instance, if the turn was 90 degrees the initial error was 1571/8 or about 196. This number was added to 127 for one motor and subtracted from 127 for the other motor and the result was clipped at MAX_ROTATION_SPEED which is currently set at 50. At 10 degrees away the PWM values were 127 +/- 21 and so on. The problem with this approach, especially for small rotations was that the PWM differential was not big enough to get the rotation going and we still overshot our target a little.

So the first attempt for the new design - “pictured” was

PWM = 127+/- (P*error in mr + I * sum of error in mr - D * angular rate(mr/sec))

The I term is set to zero if the robot is moving so it only helps to get the robot moving whe the P term is too small. Of course it also comes into play when the angular rate is near zero at the end of the rotation and that is probably needs to be fixed. I think for the data I posted P, I , and D were all 1 because we were just trying to figure out if we had the logic right. Because the magnitude of the P and D terms were too big the result was kind of an all on/all off situation. What caught my eye of course was the apparent delay in the system. As far as the loop bandwidth is concernded.
when the gyro is being used the loop runs every 26.2ms when the camera is being used and only one target is detected the loop runs at about 1/3 that rate and when two targets are detected it runs at about 1/6 of that rate since it takes the whole, left, and right virtual windows to get a two target solution.

Yes, it does make sense and thankyou for taking the time to help. As for the picture, to be honest it was such a wirlwind spring break trip I don’t remember now - I’ll look through the pictures and figure that out!

  • Greg

Thanks for the info. Delayed gyro data would also explain what I am seeing but I haven’t noticed that before. I think I can run a little test by rotating the gyro and stop the rotation with closing a limit switch and look at the timing from when the SW sees the digital input change to when the gyro heading changes stop. I do know that the gyro is dead on accuracy wise after it is calibrated but there could be a lag. I’ll post the results of the lag experiment.

Thanks,

Greg

You may want to get out a magnifying glass and inspect the caps and resistors on the break out board. On our 2007 gear tooth sensor I notice 2 components were not soldered. They were bent up and not in contact with the pad. I believe there are several components on the board that set the gyro" s internal filter. If they are not soldered correctly that could give very unusual outputs.

Greg,
In looking at the upper curves, the PWM values make a change as soon as the gyro output decides it has gone past the target, so I don’t think you have delay in that part of the system. i.e. no delay in the gyro, software or PWM output. As I remember, the Victor has an output frequency of 150 Hz (old ones were in the 2kHz range) so there could be some delay before an input change would make a change in the output but that still would only be 10-20 mSec. I still think you are dealing with mechanical motion. You mentioned in an earlier post that you are using a transmission and chain drive. I would think that you could easily calculate the delay in taking up the slack in a chain at the output RPM of the transmission and add that to the other known delays and see if you are getting any closer to the measured result.
The picture background reminded me of the Philmont area near Cimmarron, just east of Angel Fire.

I’ll be very interested to see that data :smiley:

The gyro not withstanding, I also agree with Al… mechanical systems like these robots come with large inherent delays built in.

If you want to determine the fastest response time of the drive/gyro, you could drive it with a Victor (just for a test). This would eliminate any pwm latencies. At least it would provide a mechanical/feedback best-case baseline.

Al,

I agree that a lot of the delay just has to be mechanical but I would think that even while the armature starts to back off and then the gear teeth disengage and the chain starts to slack (whatever the right terminology is) there would be some hint of system response as soon as the wheels start to slow down but maybe that doesn’t even happen for over 100ms. I think that if the gyro response was delayed (although I don’t understand how it could be delayed that much unless there are assembly problems as Gdeaver has suggested) then that might explain part of what I am seeing as well. I have an experiment in mind that I will try to carry out sometime this weekend. Basically what I was thinking of doing is to first drive a turntable with a VEX motor with the gyro on it and directly connect a grayhill 256 count per turn shaft encoder and also put a tab on the turntable and have it run through an optical interrupter limit switch. Then set up some simple code to turn it back and forth at different rates and see what the gyro and the shaft encoder are saying. The optical interrupter would give the truth data on the actual orientation. It seems to me that I should be able to see what the lag of the gyro (and shaft encoder to boot assuming there may be issues with that driver). The other experiment on the output side will be to toggle a digital output when the PWM value is changed and see how long it takes to show up on the PWM output. Others have posted that for PWM 1-12 it can be on the order of 50ms. So I will try with PWM1 and PWM 15 to get that data. I imagine there will be a lot of jitter in the delay for PWM1 to PWM 12 so it would be nice to automate that measurement some how and get some statistics - that is probably a bridge too far but a couple of my old standby HP Universal Time Interval Counters could record and dump that kind of data.

Then, if I have those measurements and especially if the PWM output has low jitter using the PWM 15 (Kevin Watson’s Timer 3 code) then I could drive the turntable with a VEX gear train and chain to get a real world feeling for the mechanical linkage delays. Being a DSP/communications systems EE type I am really a fish out of water on the mechanical side and I just don’t have a good gut feeling for what to expect there.

I’ll post whatever data I get.

As for Philmont, I would really like either or both of my sons to go and I wouldn’t mind tagging along! Sea Base and Northern Tier seem to be more of an interest.

Thanks again,

Greg

Greg,
This will be my first calculation on this so feel free to check me. I made this on the assuption that a system is using the big Chalupa with a 18:1 transmission feeding the chain. So backing into a time period of one revolution at 1200 RPM (max power on the curve vs speed), one rev would take .05 seconds. Assuming that the chain slack and all the gear slack could take about 1/4 of a turn to overcome at the output shaft, then the input shaft would have to turn 4.5 turns. So 4.5 x .05 seconds= 225 mSec, very close to the delay you are experiencing. Fudge in your actual speed and you will get even closer I bet. Does this sound feasible?

I got some preliminary data today on the Gyro response (still no direct measurements on PWM output delay or Victor delay)

The test setup picture is attached. The gyro/accelerometer board is taped to the top of a VEX wheel on a vertical shaft. The shaft is driven by a chain from a VEX motor. The other end of the shaft is directly drives a grayhill 256 pulse per revolution shaft encoder. Also in the setup is a slotted optical interrupt switch that a tab mounted on the wheel goes through. This provides a known position and was mostly just to make sure the shaft encoder was not missing or duplicating any pulses.

In summary, the gyro works well to a rate of about 148 degrees/sec. The gyro output (given our code infrastructure lags the shaft encoder output by about 150ms but there are no long (on the order of a second) settling delays in this data. We use Kevin Watson’s ADC and Gyro code setup for 5 analog inputs and combined sample clock of 1000Hz - each channel is setup to average two samples so the sample rate of the gyro is either 100 or 200Hz depending on how you look at it. The other channels are the Y axis accelerometer (output from the accelerometer is also in the raw data dump), the arm angle pot, the ultrasonic foot detector, and the LCD display button decoder (analog voltages for left/right/up/down and enter). The gyro code is modified to read in milli-radians and outputs measurements from 0 to (2000Pi -1) - 0 degrees -> 0 90 degrees E -> Pi/2 and so on.

The time from a PWM control change until the shaft encoder detected a rate change either for starting or stopping was less than 50ms. This delay includes the PWM output delay plus the motor and internal VEX motor gear delay plus whatever chain slack there is. This data was using PWM15 with Kevin Watson’s PWM driver code using timer 3. I also have data using PWM1 but have not had the time to reduce it.

As for the test the code is below. Basically before there is any motion our standard gyro bias measurement period (100ms) elapses and then the wheel rotates clockwise (as seen from above) until the tab on the wheel interrupts the optical detector. The wheel then is driven counterclockwise until the shaft encoder count of 100 is reached and then the motors are stopped for three seconds. Then the wheel is reversed and runs clockwise again until the shaft encoder count reaches -100 turn off motors and wait for 3 sec then the whole process repeats.

It turns out that for whatever reason the VEX motor moves a lot faster counter clockwise that clockwise.

The “raw” data capture text file is attached if anyone wants to do some more data analysis. See the printf in the code section so you know what is being printed out. The PU = XX% is the processor utilization measurement output that I forgot to turn off. It and the Gyro = lines just schedule themselves to run once a second.

If you think that these measurements are not valid or could be improved or would like some more data or change in a test case let me know while I still have this test setup together. I’ll probably try a couple more things as well.

Greg

typedef enum{
INITIALIZE,
TURNING_CLOCKWISE,
TURNING_COUNTERCLOCKWISE,
WAITING,
FINISHED
} GYRO_TEST_STATE;
GYRO_TEST_STATE gyro_test_state = INITIALIZE;

#define GYRO_TST_C_RATE 25
#define GYRO_TST_CCR_RATE -25
void GyroTestIdleOver(long clockwise)
{
if(clockwise)
{
gyro_pwm_offset = GYRO_TST_CCR_RATE;
gyro_test_state = TURNING_COUNTERCLOCKWISE;

}
else{
gyro_pwm_offset = GYRO_TST_C_RATE;
gyro_test_state = TURNING_CLOCKWISE;
}
}

void Process_Data_From_Master_uP(void)
{
static unsigned char i;
int debug_shaft_count;

.
.
.

/****************** THIS IS GYRO RESPONSE TEST CODE *****************************/
debug_shaft_count = (int)Get_Encoder_1_Count();

switch (gyro_test_state)
{
case INITIALIZE:
if(!rc_dig_in17) // When the wheel tab interrupts the IR the wheel is at zero orientation
{
Reset_Encoder_1_Count();
Set_Gyro_Angle(0);
gyro_pwm_offset = -25;
gyro_test_state = TURNING_COUNTERCLOCKWISE;

    }
 break;

 case TURNING_CLOCKWISE:
    if(debug_shaft_count < -100)
    {
       ScheduleEventTimer(GyroTestIdleOver,3000,1); // Schedule GyroTesterIdleOver(1) to run in 3000 ms
       gyro_pwm_offset = 0;
       gyro_test_state = WAITING;      
    }     
 break;

 case TURNING_COUNTERCLOCKWISE:
    if(debug_shaft_count > 100)
    {
       ScheduleEventTimer(GyroTestIdleOver,3000,0);
       gyro_pwm_offset = 0;
       gyro_test_state = WAITING;
    }
 break;

 case WAITING:

 break;
 case FINISHED:
    gyro_pwm_offset = 0;
 break;     

}
pwm01 = pwm15 = 127 + gyro_pwm_offset;
printf(“%d, %d, %d, %d, %d\r”,(int)rc_dig_in17,debug_shaft_count,(int)Get_Gyro_Angle(), (int)pwm01, (int)Get_Accel_Accel());

#ifndef _RC_8520
// see pwm_readme.txt for information about PWM();
PWM(pwm13,pwm14,pwm15,pwm16);
#endif
Putdata(&txdata); /* DO NOT CHANGE! */
}

initial_gyro_test_results.pdf (148 KB)
gyro_tst6.txt (43 KB)




initial_gyro_test_results.pdf (148 KB)
gyro_tst6.txt (43 KB)

Well, your Gyro looks a lot better behaved than mine was.
I’m assuming you are also just using the KOP gyro?

Also, What gyro dead band were you using?

Thanks for the great data… I’m going to look at it in detail.
It also restores my faith in the Gyro a bit :smiley:

Yes this is the 2007 Gyro/Accelerometer board that we got in trade from another team for our gear tooth encoders that we did not use this year.

#define GYRO_DEADBAND 4

I have some better data with the CCW rate slowing down every cycle with the idea being to determine if the gyro lag has anything to do with the rate. This data also shows some drift. I haven’t had the time to really analyze it.

different_rate_gyro_overview.pdf (542 KB)


different_rate_gyro_overview.pdf (542 KB)

The Victor updates at 120Hz. Worst case performance (assuming you have to wait the entire 26.2 ms to send the command to the master uP and you have to wait 8.3 ms for the Victor update) should be about 34.5 ms.

Note that the status lights and the movement of the motor are NOT good ways to confirm this. The status lights have some buffering in them, and motors take awhile to spin up or down (especially with gearing or loads attached). If you measure the lag between motor command setting and sensor output, then you are taking into account:

  1. User to master uP communication
  2. Actual Victor lag
  3. Motor lag
  4. Sensor lag

Try hooking the outputs of the Victor to an oscilloscope to verify. You can pulse a square wave on the Victor (i.e. output 127, 254, 127 at a certain frequency) while also pulsing a digital output pin. Look at both outputs to find the actual values for #1 and #2 above.

Remember this… the victor CHOPS at 120Hz on its output (which is dang slow, hence the angry buzzing all first robots seem to make).

The victor can only take input at a rate of about 100Hz (98Hz if your cautious). I wrote myself a two channel pwm driver using CCP’s to make a high update rate traction motor servo for our robot and found that there was a control output delay of just microseconds from control input to output when you use an output hardwired in the processor and use an oscilloscope triggering on the control input and measureing the shift on the output by having channel 2 on your scope hooked on to M+.

Mechanics do add some latency, but the thing you really have to watch is that most people are running their pwm’s on the default ifi 26.2ms basis, not on a timebase of your own.

My suggestion is just to set up a freerun timer, use eccp1 as a timebase, then eccp2 and eccp3 as duty cycle triggers (set them in hardware to initialize pin high then clear + interrupt on compare match). not only do you get a nice high update rate, but you get 16x the resolution on your motor drives. VERY nice for pid’s, made a world of difference with the resolution and the update rate increase.

any ?'s just hit me up. I can dig up my research notes on the victor period times n such if anybody wants it, i’ll scan the pages in and hopefully somebody reads bad handwriting… :ahh:

-q

Every official IFI post I’ve read about the Victor says that there are 94 discrete speed steps in both the forward and backward directions. While using custom PWM programming could increase update rate, I am skeptical of the claim that you gain any resolution improvements.

To add some explanation…
The output frequency of the Victor was reduced in this model vs the previous model. With the type of motors we use, the 120 Hz rate works better when considering the brush design and rep rate of brush and commutator. This allows better average current control for the motors.
From IFI FAQ for Victors…:The Victor will turn ‘On’ at a value of 138 and it will be at Full Forward condition at a value of 232, which is 94 steps. The output will vary linearly from 3% to 100% over these 94 steps." This compensates for the poor performance of the pots in standard joysticks.

This thread got me wondering what the exact delay is for generating PWMs 1-12. Last year, based on some crude testing, I noticed that there seemed to be about a 50 millisecond delay between setting a PWM value and seeing a response (as Greg references in his first post). This observation came from monitoring the dashboard data and was therefore, not very accurate. Yesterday, I did some additional testing and here are the results.

  • PWMs 1-12 are generated by the master processor in groups of 3 (1-3, 4-6, 7-9, 10-12). Within each group the pulses are generated simultaneously with only the pulse width varying. Each group follows the start of the previous group by approximately 2 milliseconds. Therefore the previous group pulses are completed (no matter what the pulse width) before the next group is started. This ensures a constant frequency independent of the pulse width of previous groups.

  • The delay between setting the PWM variable and seeing the start of the pulse on the output pin can be up to the following:
    Group 1 (PWMs 1-3) - 43 milliseconds
    Group 2 (PWMs 4-6) - 45 milliseconds
    Group 3 (PWMs 7-9) - 47 milliseconds
    Group 4 (PWMs 10-12) - 49 milliseconds

  • The minimum delay before the Victor can respond will be at least 1 millisecond and up to 2 milliseconds more depending on the pulse width. The Victor output frequency and mechanical delays will increase the time before you see a response as well.

  • The delay is dependant on when the PWM variable is set in the code. The delays shown above are based on setting the PWM variable at the start of the routine “Process_Data_From_Master_uP” (and are therefore maximum values). If your user code takes 10 milliseconds to execute and you set a PWM value at the end of this time, then the delay before the “new” pulse is generated will be 10 milliseconds less. From what I can see, executing the routine PUTDATA does not immediately send the updated data to the master processor. This only occurs once every 26 milliseconds, probably at nearly the same time that new OI data is being received. Either that, or the Master processor doesn’t act on the new data until the end of the 26 millisecond period.

Test Setup - The entire test was performed using only the RC. The PWM output to be tested was connected to Digital Input #3 (interrupt enabled). Each pulse width was timed to an accuracy of 1/4 millisecond. The PWM to be tested was normally set at “254” (2 milliseconds). Roughly once a second (every 40 calls to Process_Data_From_Master_uP) the PWM was changed to a value of “0” and the elapsed time between setting the PWM and observing the first 1 millisecond pulse (actually 1.25 milliseconds or less) was timed to an accuracy of 1/4 millisecond. Once the pulse was seen, the PWM value was reset to 254 in preparation for the next test, 1 second later. Data was very consistent. (OI & RC were tethered)

A second test was performed by delaying the setting of the PWM to “0” from the start of the Process_Data_From_Master_uP by putting in a 10 millisecond delay at the beginning of the routine. This resulted in delay values exactly 10 milliseconds less than the first test.

Mike