model - TiboLGH/solextronic GitHub Wiki
Cette page decrit :
- le modèle de calcul des signaux d'allumage et d'injection en fonction des entrées
- le programme permettant d'appliquer ce modèle Les entrées de ce modèle sont :
- les tables d'avance et de remplissage
- températures moteur et air
- position de l'accélerateur
- pression d'admission
- tension de la batterie
- régime moteur
Ce même modèle tourne dans le microcontroleur, ce programme permet de la debugger et de l'affiner "confortablement" (avec des sorties graphiques, des conditions stables, pas de contraintes de vitesse/taille de code...).
En ce qui concerne l'injection, il y a 2 valeurs à determiner à chaque rotation du moteur :
- la durée d'injection
- la phase de l'injection (ou temps de démarrage de l'injection par rapport au PMH)
En effet, on réalise ici une injection phasée ou synchrone qui consiste à envoyer le carburant sur une période précise (au moment où le moteur aspire de l'air).
Pour déterminer le temps d'injection tInj, il faut avoir :
- la quantité de carburant nécessaire : Qfuel (en gramme)
- le débit de l'injecteur : InjRate (typiquement en cc/min dans les caracteristiques d'injecteur, sera convertit en g/ms en interne)
- le temps mort d'ouverture de l'injecteur : InjOpen (en us)
Le débit de l'injecteur est considéré constant (dépends de l'injecteur lui-même et de la pression d'essence), le temps d'ouverture dépends de la tension de la batterie. La quantité de carburant à injecter dépends de la formule suivante :
-
QFuel = QAir / AFR
-
AFR est le rapport Air/essence (en masse, pas en volume !). Le rapport idéal est de 14.7 pour l'essence pure. * une valeur plus élevée appauvrit le mélange, on consomme moins (mais la puissance baisse, on risque la surchauffe) * une valeur plus faible enrichit le mélange, on consomme plus. La puissance augmente (jusqu'à être vraiment trop riche) * Pour solextronic, on va viser une valeur constante de 12.0 qui donne la meilleure puissance d'après [http://www.megamanual.com/begintuning.htm#chemistry]. Au diable la conso ! * Cette valeur est tout de même réglable.
-
QAir est la quantitée d'air admise à chaque tour de moteur.
QAir dépends de plusieurs paramêtres et se calcule à travers la loi des gaz parfaits :
-
PV = nRT => n = PV / RT avec
- n la quantitée d'air en mole
- P la pression de l'air : sera déduit du capteur de pression MAP (kPa)
- V le volume absorbé à chaque tour, donc la cylindrée (m3)
- R la constante des gaz parfaits (8,3144621 J.mol-1.K-1)
- T la temperature d'admission, mesurée avec le capteur IAT (en °kelvin)
QAir se déduit de n à travers la masse molaire de l'air (MMair):
- QAir = n . MMAir Et donc
- QFuel = QAir / AFR
- QFuel = n . MMAir / AFR
- QFuel = MMAir/AFR . PV / RT
Tout parait simple ! Sauf qu'il y a quelques "détails":
- La pression dans le cylindre n'est pas tout à fait la pression dans la tubulure d'admission mesurée par le capteur MAP. En effet, le cylindre ne se "remplit" pas parfaitement (pertes dans le carter, les transferts, l'échappement...). De plus, la mesure fait par le capteur MAP risque d'être diffcile à exploiter sur un 2 temps mono-cylindre. Pour tenir compte de ces phénomènes, on va introduire un facteur VE appeler le remplissage ou VE ("Volumetric Efficiency" en anglais). C'est le gros point de réglage, sachant que ce remplissage varie en fonction du régime, de la charge et du moteur. On en déduit :
- P = VE(RPM, load, MAP).Patm
- La température mesurée à l'admission n'est pas exactement la température dans la chambre de combustion : il faut donc inclure un biais (plus ou moins pifométrique).
On en déduit l'équation complete :
- QFuel = MMAir/AFR . PV /RT
- QFuel = MMAir/AFR . VE(RPM, load, MAP).Patm.CYL / RT
- QFuel = MMAir/AFR . VE(RPM, load, MAP).Patm.CYL / (R.(IAT + 273))
- QFuel = MMAir.CYL/(AFR.R) . VE(RPM, load, MAP).Patm / (IAT + 273)
- QFuel = K . VE(RPM, load, MAP) / (IAT + 273)
K regroupe les constantes et pseudo-constantes (AFR et CYL qui ne changent pas en cours de fonctionnement, Patm est mesuré une fois au démarrage).
- K = MMAir.CYL.Patm / AFR.R
Comment déterminer VE(RPM, load, MAP) ? Et bien c'est là tout le problème. En fait, on va passer par une table qui va donner ce fameux VE en fonction du régime (RPM) et de la charge (load). Dans ce parametre load, variant de 0 à 100%, on peut inclure :
- la pression dans l'admission : c'est une cartograhie P/N
- la position du papillon des gaz : c'est une cartographie alpha/N
- un débitmetre (capteur MAF) : c'est une cartographie D/N (D pour débit) Pour commencer, on va utiliser une cartographie alpha/N, réputée suffisant sur les moteurs "de course" (comprendre pas fait pour les mi-régimes).
Cette équation donne la quantité idéale de carburant. Cette valeur doit être modifiée dans plusieurs cas dynamiques :
- pendant le démarrage (cranking) : startInj, cette valeur s'arrête dès que l'on passe les 1000 tr/min. C'est une valeur fixe.
- juste après le démarrage : afterStartEnrich qui dure 60sec et dont la valeur dépends de la température de démarrage.
- sur le plus long terme : warmupEnrich jusqu'à obtenir la bonne temperature de moteur (capteur CLT)
- à l'ouverture des gaz (reprise) : accEnrich basée sur la vitesse de variation du TPS.
- par un biais ajouté par le pilote à travers l'interface bouton/LCD : injOffset
- en cas de fermeture des gaz (deccélération) : decEnrich
- en cas de surchauffe, on va enrichir le mélange pour améliorer le refroidissement : overHeatEnrich
Ce sont les cas les plus simples. En temps que moteur destiné à la compétition, on peut se limiter aux cas les plus simple : le démarrage à -30°C ou la diminution de la pollution ne sont pas des critères importants dans notre cas, on peut largement se concentrer sur la puissance max à tous les régimes et le comportement en cas d'ouverture/fermeture rapide des gaz (on est rarement à mi-gaz...). On arrive donc à la formule suivante:
-
QFuel = K . VE(RPM, load, MAP) / (IAT + 273) . enrich / 100
avec
- enrich = afterStartEnrich + warmupEnrich + accEnrich
A partir de QFuel, on peut déterminer la durée d'injection InjPW:
- InjPW = QFuel/InjRate + InjOpen(Vbat)
avec InjOpen(Vbat) une table qui donne le temps d'ouverture de l'injecteur en fonction de la tension de la batterie.
Reste à déterminer à partir de quand on peut lancer l'injection de carburant. L'idée est de démarrer l'injection quand les clapets d'admission s'ouvrent pour profiter de la colonne d'air en mouvement. Cette valeur va dépendre du moteur et est défini par un angle après le PMH.
- TstartInj = AngleClapet . Tcycle / 360
Avec Tcycle le temps pour un tour moteur.
Pour Tcycle, on remarque que on a besoin de sa valeur avant de pouvoir le mesurer ! Pour tenir compte de la variation de régime, on va "prédire" la valeur du prochain cycle en fonction des cycles précédents :
- Tcycle = Tcycle(N-1) + (Tcycle(N-1) - Tcycle(N-2))
- Tcycle = 2.Tcycle(N-1) - Tcycle(N-2)
Le réglage dynamique de l'avance à l'allumage est un peu plus simple, ou plutot il y a moins de formule et potentiellement plus de "feeling" ;-).
Comme pour l'injection, une table va déterminer l'avance à appliquer en fonction du régime (RPM) et de la charge (load). Cette table aura les même entrées que la table de VE pour réduire un peu l'occupation mémoire. Cette table donnera l'avance par rapport au PMH en deg, valeur qui sera convertie en timing à travers :
- Tigni = (360 -Advance) . Tcycle / 360
L'avance sera aussi modifiée dans les cas suivants :
- Surchauffe ou surrégime : on appliquera un retard défini par ignOverheat
- un bias appliqué par le pilote : ignOffset
- au démarrage (cranking), l'avance sera fixe à starterAdv jusqu'à ce que le moteur atteigne 1000tr/min
La courbe de base consiste à avoir une faible avance à très bas régime, puis monter rapidement jusqu'à 25-30° vers 3000tr/min et redescendre doucement jusqu'à 7-10° à 10000 tr/min => voir les courbes du Shadocs comme données de base.
En plus de l'avance, le logiciel doit gérer le temps de recharge du condensateur. En fait, ce n'est pas obligatoire, ça permet juste de diminuer la consommation électrique. Pour cela il va falloir déterminer le temps nécessaire au convertisseur haute-tension pour charger le condensateur du cicuit CDI à la valeur attendue (~300-320v). Cette valeur dépendre de la tension de la batterie, étude un peu plus précise à faire.
- PMH et détecteur
- influence de la vitesse ??
Quelques sites donnant des explications détaillées (mais en anglais et avec des unités américaines) : Megasquirt Tuning guide
Le réglage des tables de VE et d'avance à l'allumage sur toute la plage de fonctionnement est une opération difficile sans matériel adapté. La plupart des fabricants d'ECU conseille d'utiliser un banc de mesure de puissance et une sonde lambda "wide band" (qui permet de mesure l'AFR à travers les gaz d'échappement). Les sites de réglages se basent beaucoup sur la sonde lambda et des tests sur routes, principalement parce que le test sur un banc de mesure de puissance est très coûteux pour une voiture (il faut en plus un banc dit "statique" qui agit comme un frein et non "dynamique" qui mesure la puissance à travers l'accélération).
Dans le cas du Solex, c'est un peu différent : la réalisation d'un banc de mesure de puissance est possible pour un cout raisonnable (objectif vers les 200€) et la procédure de réglage devient plus simple. De plus, en tant que moteur de compétition, on peut envisager pas mal d'évolution et donc de re-réglage : il faut une procédure la plus automatisée possible pour pouvoir refaire cette optimisation à chaque évolution mécanique.
Pour cela, le développement d'un banc de mesure de puissance statique est un point important. Il permettra :
- de faire les premiers réglages de façon "confortable" dans un environnement contrôlé plutôt que sur la route
- de faire l'optimisation semi-automatique des courbes d'injection et d'allumage
- de mesurer et comparer les performances moteur à chaque modification mécanique
Ce banc pourrait être basé sur un alternateur automobile comme présenté sur le site de Bernique.
TODO : conception d'un banc de mesure de puissance/optimisation des tables injection/allumage.
- calcul de la taille d'injecteur optimal
- calcul des timings d'avance à l'allumage pour comparaison avec la simulation
- calcul des timings d'injection pour comparaison avec la simulation
Ce logiciel est écrit en Python (Python3) avec les bibliothèques suivantes:
Note: les 1ere version étaient écrites en C mais étaient trop lourdes à développer pour être vraiment utiles.
L'installation des dépendances se fait avec les commandes suivantes :
pip3 install numpy
pip3 install matplotlib
Le fichier model.ini contient l'ensemble des parametres nécessaires au calcul
Les tables sont typiquement stockées dans les fichiers ignition.csv et injection.csv. Il doit y avoir exactement 11 lignes (1 par RPM + 1 d'en-tete) et 11 colonnes (1 par charge + 1 d'en-tete). Le fichier ignition.csv doit comporter le keyword "Ignition" sur la 1ere ligne, 1ere colonne. Pareil pour le fichier injection.csv avec le keyword "Injection".
solextronic/solextronic/model} model.py -h
usage : ./model.py [options]
Les options valides sont :
-h affiche ce message
-
-v affichage des traces de debug
-f calcul du debit de l'injecteur (calcul des tables de timings par default)
-i <inifile> utilisation du fichier <inifile> a la place de model.ini
Ce mode est utilisé typiquement par le module de simulation pour vérifier les calculs fait par le firmware. Dans ce mode, model.py lit les fichiers de configurations (image de la config stockée en EEPROM) et l'état courant (image de la structure gState) pour effectuer le calcul d'injection et d'allumage.
> model.py testinj -e eeprom.bin -g gstate.bin -o result.bin
> model.py testign -e eeprom.bin -g gstate.bin -o result.bin
Ce mode est utilisé pour faire des simulations de scenarios et extraire les courbes injection/allumages correspondantes. Plusieurs scenarios seront implementés :
- démarrage (cranking)
- ralenti
- accélération
- décceleration
- surchauffe
Liste les scenarios disponibles
> model.py analyze -l
Lance le scenario "exemple"
> model.py analyze -r "exemple"
Le fichier convert.py permet d'encoder/décoder des fichiers binaires EEPROM et state (état courant). Il permet aussi d'extraire/écrire les tables de cartographie pour l'injection et l'allumage à partir de fichiers CSV simples.
Conversion binaire vers JSON (le type de structure est devinée automatiquement):
> convert.py bin2json -i eeprom.bin -o eeprom.json
Conversion JSON vers binaire:
> convert.py json2bin -i eeprom.json -o eeprom.bin
Extraction cartographie (bin ou json détecté automatiquement):
> convert.py extractcsv -i eeprom.bin -o carto.csv