T09 · Ingénierie pratique CAKE© · Chapitre 3 / 11

Chaînes de transformation CAKE©

Constantes d'un côté, mission de l'autre : la chaîne .cpx + .cps

Une chaîne de transformation CAKE© commence rarement par du calcul. Elle commence par une séparation : ce qui varie d'une mission à l'autre, et ce qui reste identique. CakeLand matérialise cette séparation en deux types de fichiers.

Le fichier .cpx porte les constantes de variation : masse de la planète, altitude de départ, vitesse, pas de temps. Le fichier .cps porte la mission : l'algorithme qui transforme ces constantes en trajectoire. L'éditeur les assemble dans cet ordre — constantes, ligne vide, mission — puis exécute le tout comme un seul programme. Changer d'orbite, c'est changer de .cpx ; le .cps, lui, a déjà été vérifié et n'a pas à être touché.


Une chaîne minimale

Voici la chaîne réduite à l'essentiel : trois constantes, puis une mission qui calcule la vitesse circulaire et la période d'une orbite basse à 200 km, et place douze points sur le cercle.

Orbite basse : constantes puis mission

Source C% · t09c03-a.cake
?! --- constantes (.cpx) ---
=: mu=398600.4418%
=: re=6378.137%
=: alt=200.0%

?! --- mission (.cps) ---
=: r=re+alt%
=: v=Cake.sqrt(mu/r)%
=: periode=2.0*3.141592653589793*r/v%
|> "Vitesse circulaire (km/s) : " + Cake.toString(Cake.round(v*1000)/1000)%
|> "Periode (min) : " + Cake.toString(Cake.round(periode/60*10)/10)%
=: k=0%
$= (k<12) {
  =: a=2.0*3.141592653589793*k/12%
  Cake.emit(r*Cake.cos(a), r*Cake.sin(a), 0, k)%
  :+ k=1%
}
Sortie réelle du moteur
Vitesse circulaire (km/s) : 7.784
Periode (min) : 88.5
[12 point(s) transmis au visualiseur par Cake.emit]
→ valeur finale : 12
Arbre syntaxique sérialisé en CXML par l'analyseur
<projet nom="t09c03-a" package="com.unibool.script" type="Library">
  <classe nom="Root" visibilite="Public">
    <methode nom="main" retour="void" visibilite="Public">
      <bloc>
        <declaration nom="mu" type="var" valeur="398600.4418"/>
        <declaration nom="re" type="var" valeur="6378.137"/>
        <declaration nom="alt" type="var" valeur="200.0"/>
        <declaration nom="r" type="var" valeur="re + alt"/>
        <declaration nom="v" type="var" valeur="Cake.sqrt(mu / r)"/>
        <declaration nom="periode" type="var" valeur="2.0 * 3.141592653589793 * r / v"/>
        <appel methode="println" args="&quot;Vitesse circulaire (km/s) : &quot; + Cake.toString(Cake.round(v * 1000) / 1000)"/>
        <appel methode="println" args="&quot;Periode (min) : &quot; + Cake.toString(Cake.round(periode / 60 * 10) / 10)"/>
        <declaration nom="k" type="var" valeur="0"/>
        <tant-que condition="k&lt;12">
          <bloc>
            <declaration nom="a" type="var" valeur="2.0 * 3.141592653589793 * k / 12"/>
            <code-brut><![CDATA[Cake.emit(r*Cake.cos(a),r*Cake.sin(a),0,k)%]]></code-brut>
            <affectation cible="k" valeur="k + 1"/>
          </bloc>
        </tant-que>
      </bloc>
    </methode>
  </classe>
</projet
Traçabilité — opcodes : =: déclarations · |> entrées/sorties · $= flux · :+ déclarations · bibliothèque : Cake.sqrt, Cake.toString, Cake.round, Cake.emit, Cake.cos, Cake.sin
nœuds d'arbre : déclaration, appel, tant-que, code brut, affectation · empreinte d'arbre f07dd31c85028933 (reproductible : cake hash t09c03-a.cake)
vérifié le 2026-09-23 dans le moteur CakeLang, chemin de l'éditeur CakeLand, bac à sable actif.

Les deux valeurs se vérifient à la main : la racine carrée de 398 600,4418 ÷ 6 578,137 vaut bien 7,784 km/s, et une orbite à cette altitude boucle en un peu moins d'une heure et demie. Une chaîne de transformation digne de ce nom se contrôle ainsi, par un calcul indépendant, avant d'être crue.

La chaîne complète livrée avec CakeLand

Le bouton « Objet en orbite » de l'éditeur charge la même séparation à l'échelle réelle : reentry_leo.cpx pour les constantes, reentry_rk4.cps pour une intégration de Runge-Kutta d'ordre 4 qui tient compte de la gravité et d'une traînée atmosphérique exponentielle. Avec la traînée à zéro, l'orbite reste fermée ; les autres fichiers .cpx de CakeLand font varier ce seul paramètre pour montrer la décroissance puis la rentrée.

L'objet en orbite de CakeLand, tel quel

Le source ci-dessous est exactement celui que l'éditeur assemble. Remarquez 0.0-mu : c'est la manière sûre d'écrire une valeur négative dans une expression (voir le chapitre 9).

Source C% · t09c03-b.cake
?# .cpx -- CONSTANTES DE VARIATION : LEO circulaire ~200 km, sans trainee
?# Meme mission, kDrag=0 -> orbite fermee stable (cercle/ellipse).
=: mu=398600.4418%
=: re=6378.137%
=: r0x=6578.137%
=: r0y=0.0%
=: r0z=0.0%
=: v0x=0.0%
=: v0y=7.784%
=: v0z=0.0%
=: kDrag=0.0%
=: scaleH=60.0%
=: dt=20.0%
=: steps=600%

=: rx=r0x%
=: ry=r0y%
=: rz=r0z%
=: vx=v0x%
=: vy=v0y%
=: vz=v0z%
=: hh=dt*0.5%
=: h6=dt/6.0%
=: i=0%
$= (i<steps) {
  =: q0=Cake.sqrt(rx*rx+ry*ry+rz*rz)%
  =: g0=0.0-mu/(q0*q0*q0)%
  =: d0=0.0-kDrag*Cake.exp(0.0-(q0-re)/scaleH)*Cake.sqrt(vx*vx+vy*vy+vz*vz)%
  =: a0x=g0*rx+d0*vx%
  =: a0y=g0*ry+d0*vy%
  =: a0z=g0*rz+d0*vz%
  =: r1x=rx+hh*vx%
  =: r1y=ry+hh*vy%
  =: r1z=rz+hh*vz%
  =: w1x=vx+hh*a0x%
  =: w1y=vy+hh*a0y%
  =: w1z=vz+hh*a0z%
  =: q1=Cake.sqrt(r1x*r1x+r1y*r1y+r1z*r1z)%
  =: g1=0.0-mu/(q1*q1*q1)%
  =: d1=0.0-kDrag*Cake.exp(0.0-(q1-re)/scaleH)*Cake.sqrt(w1x*w1x+w1y*w1y+w1z*w1z)%
  =: a1x=g1*r1x+d1*w1x%
  =: a1y=g1*r1y+d1*w1y%
  =: a1z=g1*r1z+d1*w1z%
  =: r2x=rx+hh*w1x%
  =: r2y=ry+hh*w1y%
  =: r2z=rz+hh*w1z%
  =: w2x=vx+hh*a1x%
  =: w2y=vy+hh*a1y%
  =: w2z=vz+hh*a1z%
  =: q2=Cake.sqrt(r2x*r2x+r2y*r2y+r2z*r2z)%
  =: g2=0.0-mu/(q2*q2*q2)%
  =: d2=0.0-kDrag*Cake.exp(0.0-(q2-re)/scaleH)*Cake.sqrt(w2x*w2x+w2y*w2y+w2z*w2z)%
  =: a2x=g2*r2x+d2*w2x%
  =: a2y=g2*r2y+d2*w2y%
  =: a2z=g2*r2z+d2*w2z%
  =: r3x=rx+dt*w2x%
  =: r3y=ry+dt*w2y%
  =: r3z=rz+dt*w2z%
  =: w3x=vx+dt*a2x%
  =: w3y=vy+dt*a2y%
  =: w3z=vz+dt*a2z%
  =: q3=Cake.sqrt(r3x*r3x+r3y*r3y+r3z*r3z)%
  =: g3=0.0-mu/(q3*q3*q3)%
  =: d3=0.0-kDrag*Cake.exp(0.0-(q3-re)/scaleH)*Cake.sqrt(w3x*w3x+w3y*w3y+w3z*w3z)%
  =: a3x=g3*r3x+d3*w3x%
  =: a3y=g3*r3y+d3*w3y%
  =: a3z=g3*r3z+d3*w3z%
  =: nrx=rx+h6*(vx+2.0*w1x+2.0*w2x+w3x)%
  =: nry=ry+h6*(vy+2.0*w1y+2.0*w2y+w3y)%
  =: nrz=rz+h6*(vz+2.0*w1z+2.0*w2z+w3z)%
  =: nvx=vx+h6*(a0x+2.0*a1x+2.0*a2x+a3x)%
  =: nvy=vy+h6*(a0y+2.0*a1y+2.0*a2y+a3y)%
  =: nvz=vz+h6*(a0z+2.0*a1z+2.0*a2z+a3z)%
  := rx=nrx%
  := ry=nry%
  := rz=nrz%
  := vx=nvx%
  := vy=nvy%
  := vz=nvz%
  Cake.emit(rx,ry,rz,i)%
  :+ i=1%
}
|> "Mission RK4 terminee"%
Sortie réelle du moteur
Mission RK4 terminee
[600 point(s) transmis au visualiseur par Cake.emit]
Traçabilité — opcodes : =: déclarations · $= flux · := déclarations · :+ déclarations · |> entrées/sorties · bibliothèque : Cake.sqrt, Cake.exp, Cake.emit
nœuds d'arbre : déclaration, tant-que, affectation, code brut, appel · empreinte d'arbre ff65aeadd7b74dba (reproductible : cake hash t09c03-b.cake)
vérifié le 2026-09-23 dans le moteur CakeLang, chemin de l'éditeur CakeLand, bac à sable actif.

Pourquoi cette séparation compte

Dans une station à des centaines de milliers de points de contrôle, on ne réécrit pas l'algorithme de chaque drone pour chaque vol. On vérifie une mission une fois, on la fige par son empreinte d'arbre, et l'on ne fait plus circuler que des constantes. La surface de ce qui peut changer — donc de ce qui doit être revérifié — se réduit à quelques lignes de .cpx.

Principe clé du chapitre

Séparer les constantes de la mission, c'est séparer ce qui change de ce qui a été prouvé. Une chaîne de transformation fiable fait circuler des données, pas du code neuf.

→

Le chapitre suivant regarde de près ce que devient ce programme une fois analysé : l'arbre et sa forme CXML.

← Chapitre précédent C02 · Anatomie d'un moteur CAKE©
T09 · C03 / 11
Chapitre suivant → C04 · Représenter les architectures
CAKE© Library  ·  Sébastien Roy  ·  CEO, UniBool Inc.  ·  Canada  ·  Édition 2026