MEGAsquirt A place to collectively sort out this megasquirt gizmo

DIYPNP install: inital tuning

Thread Tools
 
Search this Thread
 
Old 06-16-2011, 12:50 PM
  #241  
Elite Member
 
JasonC SBB's Avatar
 
Join Date: Jul 2005
Posts: 6,420
Total Cats: 84
Default

Originally Posted by muythaibxr
Let me try a different way of explaining.

Lets try a decrease in RPM over 2 samples:

1200
1000
900

pwmidle_deriv = PV - (2*PV_last[0]) + PV_last[1];

900 - 2000 + 1200 = 100

That's now positive and will react in the same direction as P and I. (P and I will still be negative in this example).
In order to analyze the above you need to calculate it at at least 3 points because the final piece of code mathematically integrates the value into the solenoid:

The MS2 code effectively does this:
CO += CO_change
aka
duty = duty + change_in_duty
Remember, the 2nd derivative, the above snippet, calculates the *change* in duty cycle, not the duty cycle.

The MS2 code adds the Kd term, because it has a double negative:
tmp1 = IACmotor_pos - (((long)(Kp + Ki - Kd) * ...
Let's try that. I will add leading and trailing RPM numbers like this

1200
1200
1200
1000
900
900
900
900

I will add the 2nd derivative calculation

PHP Code:
1200 
1200 
1200        0
1000    
-200
900      100
900      100
900        0
900        0 
(the first 2 solutions I left blank because the calculation requires 2 earlier sample points)
<Jeezus how do you make a table with columns aligned?>

It looks strange, but now the numbers in the 2nd column, will be integrated into the duty cycle. I will assume that the above 2nd column (which is change in duty), is scaled by 0.1, and the starting duty cycle is 50%.

PHP Code:
1200               50%
1200               50%
1200      0       50%
1000     -200    30%
900       100     40%
900       100     50%
900       0        50%
900       0        50
Hmm, it seems backwards, it made the duty cycle dip when the slope of the RPM went negative.

Let's try it where
duty = duty - change_in_duty
as I suggest.
PHP Code:
1200             50%
1200             50%
1200     0      50%
1000    -200  70%
900     100    60%
900     100    50%
900       0     50%
900       0     50
Now the duty cycle opens up!


- If RPM is constantly increasing or constantly decreasing over time, D won't have a huge effect, but its effect will be in the same direction as P or I
D and P can have opposite effects. You can have a situation where RPM is above target (so P will shrink duty%), but RPM is *decreasing* so that D tends to *increase* duty cycle. In this situation D will "soften the landing" so RPM doesn't undershoot.

The effect of D and P and I can be any combinations of positive or negative.
JasonC SBB is offline  
Old 06-16-2011, 01:08 PM
  #242  
Elite Member
 
JasonC SBB's Avatar
 
Join Date: Jul 2005
Posts: 6,420
Total Cats: 84
Default

Now let's try a case where the RPM begins to continuously drop

1000 50%
1000 50%
1000 0 50%
1000 0 50%
950 -50 55%
900 0 55%
850 0 55%
800 0 55%

There, duty cycle opens up and stays open due to the RPM's downward slope.

So, the D term in ideal PID is the 1st derivative of the actual error. In my code, the derivative of the whole PID equation was taken (since I'm summing the end result of the whole equation instead of using a bias + the PID output), which results in the D term needing to be the 2nd derivative.

That 2nd derivative form of the D term can cause "interesting" (but still correct) behavior, but I don't necessarily think it can be directly compared to what happens in the ideal form of PID.

I do think that taking the 2nd derivative of the error and adding that instead of subtracting it (form A of PID) may have a response closer to what you're expecting though.
The difference between form A and form C is that C calculates the derivative of the setpoint as opposed to the derivative of the error. Because error = setpoint minus actual_RPM, if setpoint does not change, (e.g. always 1000 RPM), then the resulting D term is the same between type A and type C.

The fact that the code uses the 2nd derivative of RPM is irrelevant in regards to type A vs type C. The 2nd derivative technique is *not* to turn the calculation from type A to type C, it's to be able to do this as the last step:
duty = duty - change_in_duty
You could turn the MS code into type A simply by calculating the 2nd derivative of the error instead of the RPM:
derivative_of_error = error - 2*error_last[0] + error_last[1]
where
error = setpoint - RPM
and the difference would only appear when setpoint is changing (e.g. target suddenly changes from 1000 to 1100 RPM when say, the a/c turns on).


BTW in the page quoted, the part about
"engineers don't like type A because ..."
is true for industrial processes where the process variable don't change quickly (e.g. smelting temperature) and you don't want valves or whatever to be quickly slamming open or shut (e.g. big valves that have a fixed cycle life). A type A loop would cause said valves to slam open or shut if the setpoint was changed by an operator. In the case of idle or *especially* boost control, type A will be superior to type C because the target *can* change suddenly, and the solenoid valves responding to sudden changes in target are *not* a problem. Additionally if the target changes abruptly you *do* want the solenoid to quickly react in order to speed up the response.
JasonC SBB is offline  
Old 06-16-2011, 06:14 PM
  #243  
Junior Member
Thread Starter
 
Greg G's Avatar
 
Join Date: Jun 2007
Posts: 411
Total Cats: 0
Default

Originally Posted by JasonC SBB
You could turn the MS code into type A simply by calculating the 2nd derivative of the error instead of the RPM:
derivative_of_error = error - 2*error_last[0] + error_last[1]
where
error = setpoint - RPM
and the difference would only appear when setpoint is changing (e.g. target suddenly changes from 1000 to 1100 RPM when say, the a/c turns on).
Now this caught my eye. By using type A, you could potentially use a hardware trigger to change the RPM setpoint and command a more aggressive controller output response?
Greg G is offline  
Old 06-16-2011, 06:35 PM
  #244  
Elite Member
 
JasonC SBB's Avatar
 
Join Date: Jul 2005
Posts: 6,420
Total Cats: 84
Default

Its good for making the RPM rise faster if the setpoint goes up. It's minimally useful for idle control because you can simply delay the ac clutch engagement a bit more, if you have a type C controller.
JasonC SBB is offline  
Old 06-16-2011, 06:43 PM
  #245  
Elite Member
 
JasonC SBB's Avatar
 
Join Date: Jul 2005
Posts: 6,420
Total Cats: 84
Default

BTW the good news is that in my worked examples I realized that the D term reacts in one tick (rather than 2) so that "problem" doesn't exist.
JasonC SBB is offline  
Old 06-17-2011, 11:54 AM
  #246  
Junior Member
 
muythaibxr's Avatar
 
Join Date: May 2007
Location: Columbia, MD
Posts: 248
Total Cats: 0
Default

You know I hate to admit it after arguing so hard about it, but just based on how the signs change for type A vs B and C, you might be right... (Jason). I can admit when I'm wrong when it happens. I was mainly just following the site, but I see where I went wrong when following the site.

My logic here has nothing to do with the shift right or left, but the differences between types A and B, and then the further differences between types B and C, and where I put parens:

In type A, we have:

duty = duty + P + I + D

B is:

duty = duty + P + I - D (because when you change from using error calculated as SP - PV, to just using change in PV, you have to reverse the sign).

C is currently listed as:

duty = duty - P + I - D,

but I originally read it as

duty = duty - (P + I - D), which turns into duty = duty - P - I + D

now when I originally wrote the code, I noticed that this made the I term act in the wrong direction, so my "fix" was to change the error from SP - PV to PV - SP. Doing things that way P and I act in the correct direction, but D apparently doesn't.

So I was wrong, you were right, I have arrived at that conclusion on a different path but gotten the same result, so I think that doubly proves it.

I'll fix it as soon as I get a chance both in ms2 and ms3 and we'll see if it actually solves the problem you (Greg) were trying to fix.

So what I should probably really do is change error to SP - PV, and invert the signs on the I term and the D term inside the parens.

Now, I will have to double check what I did for boost and EGO, I think based on having tuned boost and working out how the signs work with/without parens that boost is done correctly but EGO probably isn't.

Next time you want to tell me something is wrong, you won't get as much argument if you show me that the equations themselves are wrong like I just used to prove it to myself


Ken

Last edited by muythaibxr; 06-17-2011 at 12:04 PM.
muythaibxr is offline  
Old 06-17-2011, 12:01 PM
  #247  
Junior Member
 
muythaibxr's Avatar
 
Join Date: May 2007
Location: Columbia, MD
Posts: 248
Total Cats: 0
Default

Originally Posted by Greg G
Now this caught my eye. By using type A, you could potentially use a hardware trigger to change the RPM setpoint and command a more aggressive controller output response?
Already written that code in MS3.

Ken
muythaibxr is offline  
Old 06-17-2011, 12:46 PM
  #248  
Junior Member
Thread Starter
 
Greg G's Avatar
 
Join Date: Jun 2007
Posts: 411
Total Cats: 0
Default

Thanks Ken! Thanks Jason! Group hug!
Greg G is offline  
Old 06-17-2011, 12:46 PM
  #249  
Elite Member
 
JasonC SBB's Avatar
 
Join Date: Jul 2005
Posts: 6,420
Total Cats: 84
Default

Originally Posted by muythaibxr
Next time you want to tell me something is wrong, you won't get as much argument if you show me that the equations themselves are wrong like I just used to prove it to myself

Ken
I'm a hardware weenie - much easier for me to look at system behavior in datalog graphs than to look at code!
(BTW that also reads as, "my weenie is hard" as opposed to software weenies )

Good stuff. Bugs have creative ways of sneaking in and getting past testing!

Last edited by JasonC SBB; 06-17-2011 at 01:12 PM.
JasonC SBB is offline  
Old 06-17-2011, 12:51 PM
  #250  
Junior Member
 
muythaibxr's Avatar
 
Join Date: May 2007
Location: Columbia, MD
Posts: 248
Total Cats: 0
Default

Yeah, I've learned as much hardware as I need to in order to install the MS and design some basic circuits, but I'm much more of a software guy, so showing me that one of my equations is wrong usually gets an immediate result.

Actually, it's a bit funny, but I learned how engines work by reading other peoples' code to control them.

Ken
muythaibxr is offline  
Old 06-17-2011, 01:29 PM
  #251  
Junior Member
 
muythaibxr's Avatar
 
Join Date: May 2007
Location: Columbia, MD
Posts: 248
Total Cats: 0
Default

So I did some more checking, Boost is fine, no retune necessary.

EGO and Idle will need a D retune, and if you're on ms3 VVT will need D retuned.

Ken
muythaibxr is offline  
Old 06-17-2011, 01:40 PM
  #252  
Elite Member
iTrader: (11)
 
miatauser884's Avatar
 
Join Date: Feb 2009
Posts: 2,959
Total Cats: 11
Default

When will we be able to download the new code?
miatauser884 is offline  
Old 06-17-2011, 01:54 PM
  #253  
Junior Member
Thread Starter
 
Greg G's Avatar
 
Join Date: Jun 2007
Posts: 411
Total Cats: 0
Default

I think the improvements from the mariob version (or some form of them) will also be integrated to the next release. All in good time
Greg G is offline  
Old 06-17-2011, 02:03 PM
  #254  
Elite Member
iTrader: (10)
 
Reverant's Avatar
 
Join Date: Jun 2006
Location: Athens, Greece
Posts: 5,976
Total Cats: 355
Default

So in other words, the correct would be to say:

rpm_error = SP - PV;

and then:

tmp1 = IACmotor_100 - (((long)(Kp - Ki + Kd) * (flash5.pwmidle_open_duty - flash5.pwmidle_closed_duty)) / 100000);

Right?
Reverant is offline  
Old 06-17-2011, 02:12 PM
  #255  
Elite Member
iTrader: (10)
 
Reverant's Avatar
 
Join Date: Jun 2006
Location: Athens, Greece
Posts: 5,976
Total Cats: 355
Default

Btw, for EGO, I see:

egoerr = SP - PV;

and

*egostep = (long)(10L*(Kp - Ki + Kd)) / (PID_scale_factor*1000L);

Since egostep is added, and not subtracted, like this:

egotmpcor = outpc.egocor1 + ego1step;

Then can we assume that the EGO code is also wrong and needs to be converted to this:

*egostep = (long)(10L*(-Kp + Ki - Kd)) / (PID_scale_factor*1000L);

Thoughts?
Reverant is offline  
Old 06-17-2011, 02:20 PM
  #256  
Boost Czar
iTrader: (62)
 
Braineack's Avatar
 
Join Date: May 2005
Location: Chantilly, VA
Posts: 79,490
Total Cats: 4,079
Default

yeah Ken mentioned EGO and Idle needed the correction.
Braineack is offline  
Old 06-17-2011, 02:25 PM
  #257  
Ben
Supporting Vendor
iTrader: (33)
 
Ben's Avatar
 
Join Date: Jul 2006
Location: atlanta-ish
Posts: 12,659
Total Cats: 134
Default

Jason, Ken, Greg, et all, THANKS! I think this thread is a prime example of why MegaSquirt is win!

Ken, please let us know when you get a chance to brush that up, and I'll give it a test.
__________________
Chief of Floor Sweeping, DIYAutoTune.com & AMP EFI
Crew Chief, Car Owner & Least Valuable Driver, HongNorrthRacing

91 Turbo | 10AE Turbo | 01 Track Rat | #323 Mazda Champcar

Originally Posted by concealer404
Buy an MSPNP Pro, you'll feel better.
Ben is offline  
Old 06-17-2011, 02:47 PM
  #258  
Elite Member
 
JasonC SBB's Avatar
 
Join Date: Jul 2005
Posts: 6,420
Total Cats: 84
Default

Originally Posted by Ben
I think this thread is a prime example of why MegaSquirt is win!
LOL no kidding, try do that with, um, the Hydro or the AIM or the Blink ...
JasonC SBB is offline  
Old 06-17-2011, 02:55 PM
  #259  
Junior Member
 
muythaibxr's Avatar
 
Join Date: May 2007
Location: Columbia, MD
Posts: 248
Total Cats: 0
Default

Originally Posted by djp0623
When will we be able to download the new code?
Assuming I have all the time I plan on having this weekend, late Sunday evening.

IF not, no later than sometime mid-end next week.

Ken
muythaibxr is offline  
Old 06-17-2011, 03:00 PM
  #260  
Junior Member
 
muythaibxr's Avatar
 
Join Date: May 2007
Location: Columbia, MD
Posts: 248
Total Cats: 0
Default

Originally Posted by Reverant
So in other words, the correct would be to say:

rpm_error = SP - PV;

and then:

tmp1 = IACmotor_100 - (((long)(Kp - Ki + Kd) * (flash5.pwmidle_open_duty - flash5.pwmidle_closed_duty)) / 100000);

Right?
Looks right to me.

What you have there expands to

tmp1 = IACmotor_100 - Kp + Ki - Kd, which is correct.

Ken
muythaibxr is offline  


Quick Reply: DIYPNP install: inital tuning



All times are GMT -4. The time now is 10:37 AM.