diff --git a/Notice d'utilisation des signaux_complexes_GL_V6.0.pdf b/Notice d'utilisation des signaux_complexes_GL_V6.0.pdf index 981483a..141c6cf 100644 Binary files a/Notice d'utilisation des signaux_complexes_GL_V6.0.pdf and b/Notice d'utilisation des signaux_complexes_GL_V6.0.pdf differ diff --git a/UnitAnalyseSegCDM.dfm b/UnitAnalyseSegCDM.dfm index d5096ec..c54d2dd 100644 --- a/UnitAnalyseSegCDM.dfm +++ b/UnitAnalyseSegCDM.dfm @@ -1,8 +1,6 @@ object FormAnalyseCDM: TFormAnalyseCDM - Left = 216 - Top = 23 - Hint = '(aiguillages uniquement)' - Anchors = [akLeft, akTop, akRight, akBottom] + Left = 154 + Top = 36 AutoScroll = False Caption = 'FormAnalyseCDM' ClientHeight = 660 @@ -14,7 +12,6 @@ object FormAnalyseCDM: TFormAnalyseCDM Font.Name = 'MS Sans Serif' Font.Style = [] OldCreateOrder = False - ShowHint = True OnCreate = FormCreate OnResize = FormResize DesignSize = ( @@ -26,7 +23,7 @@ object FormAnalyseCDM: TFormAnalyseCDM Left = 8 Top = 16 Width = 977 - Height = 553 + Height = 537 HorzScrollBar.Tracking = True Anchors = [akLeft, akTop, akRight, akBottom] AutoScroll = False @@ -42,15 +39,15 @@ object FormAnalyseCDM: TFormAnalyseCDM end object GroupBox1: TGroupBox Left = 16 - Top = 576 - Width = 457 - Height = 73 + Top = 560 + Width = 257 + Height = 89 Anchors = [akLeft, akBottom] Caption = 'Affichages ' TabOrder = 1 object Label1: TLabel - Left = 216 - Top = 16 + Left = 24 + Top = 56 Width = 81 Height = 13 Caption = 'Afficher le port n'#176 @@ -60,7 +57,10 @@ object FormAnalyseCDM: TFormAnalyseCDM Top = 16 Width = 97 Height = 17 + Hint = 'Points de connexions des ports des d'#233'tecteurs et des actionneurs' Caption = 'Connexions' + ParentShowHint = False + ShowHint = True TabOrder = 0 OnClick = CheckConnexionsClick end @@ -69,7 +69,10 @@ object FormAnalyseCDM: TFormAnalyseCDM Top = 32 Width = 97 Height = 17 + Hint = 'Adresses des d'#233'tecteurs et actionneurs' Caption = 'Adresses' + ParentShowHint = False + ShowHint = True TabOrder = 1 OnClick = CheckAdressesClick end @@ -77,7 +80,7 @@ object FormAnalyseCDM: TFormAnalyseCDM Left = 112 Top = 16 Width = 81 - Height = 17 + Height = 25 Caption = 'segments' TabOrder = 2 OnClick = CheckSegmentsClick @@ -87,20 +90,23 @@ object FormAnalyseCDM: TFormAnalyseCDM Top = 32 Width = 121 Height = 17 + Hint = 'Affiche le num'#233'ro de segment et le port de CDM' Caption = 'Ports' + ParentShowHint = False + ShowHint = True TabOrder = 3 - OnClick = CheckSegmentsClick + OnClick = CheckPortsClick end object EditPort: TEdit - Left = 304 - Top = 16 + Left = 112 + Top = 56 Width = 57 Height = 21 TabOrder = 4 end object ButtonAffPort: TButton - Left = 368 - Top = 16 + Left = 176 + Top = 56 Width = 73 Height = 25 Caption = 'Afficher le port' @@ -121,4 +127,89 @@ object FormAnalyseCDM: TFormAnalyseCDM TabOrder = 2 OnChange = TrackBar1Change end + object GroupBox2: TGroupBox + Left = 280 + Top = 560 + Width = 145 + Height = 89 + Anchors = [akLeft, akBottom] + Caption = 'Strat'#233'gies d'#39'importation' + TabOrder = 3 + object CheckDebugAnalyse: TCheckBox + Left = 16 + Top = 24 + Width = 121 + Height = 17 + Caption = 'Debug importation' + TabOrder = 0 + OnClick = CheckDebugAnalyseClick + end + object CheckDebugBranches: TCheckBox + Left = 16 + Top = 48 + Width = 97 + Height = 17 + Caption = 'Debug branches' + TabOrder = 1 + OnClick = CheckDebugBranchesClick + end + end + object GroupBox3: TGroupBox + Left = 432 + Top = 560 + Width = 537 + Height = 89 + Anchors = [akLeft, akBottom] + Caption = 'Param'#232'tres' + TabOrder = 4 + DesignSize = ( + 537 + 89) + object ButtonImporter: TButton + Left = 382 + Top = 40 + Width = 75 + Height = 25 + Hint = 'Lancement de l'#39'importation' + Anchors = [akLeft, akBottom] + Caption = 'Importer' + ParentShowHint = False + ShowHint = True + TabOrder = 0 + OnClick = ButtonImporterClick + end + object RadioGroup1: TRadioGroup + Left = 8 + Top = 24 + Width = 305 + Height = 57 + Caption = 'Adressage des croisements' + TabOrder = 1 + end + object RadioCroisSuite: TRadioButton + Left = 24 + Top = 40 + Width = 217 + Height = 17 + Caption = 'Croisements '#224' la suite des aiguillages' + TabOrder = 2 + end + object RadioCroisBase: TRadioButton + Left = 24 + Top = 56 + Width = 217 + Height = 17 + Caption = 'Croisements '#224' partir de l'#39'adresse de base' + TabOrder = 3 + end + object EditBaseCrois: TEdit + Left = 240 + Top = 54 + Width = 41 + Height = 21 + TabOrder = 4 + Text = '100' + OnChange = EditBaseCroisChange + end + end end diff --git a/UnitAnalyseSegCDM.pas b/UnitAnalyseSegCDM.pas index 61b234e..d379c43 100644 --- a/UnitAnalyseSegCDM.pas +++ b/UnitAnalyseSegCDM.pas @@ -1,14 +1,14 @@ unit UnitAnalyseSegCDM; -// attention manque aiguillage triple -// les Tjs ne sont pas traitées, de même que les bretelles double jonction, ni les tables tournantes. +// les Tjs ne sont pas traitées, de même que les bretelles double jonction interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, - Dialogs, UnitPrinc, ExtCtrls, StdCtrls, ComCtrls, UnitDebug, UnitConfig; + Dialogs, UnitPrinc, ExtCtrls, StdCtrls, ComCtrls, UnitDebug, UnitConfig , StrUtils; const cadre=30; + const max_db = 20; // 20 détecteurs maxi entre 2 aiguillages type TFormAnalyseCDM = class(TForm) @@ -23,6 +23,15 @@ type Label1: TLabel; EditPort: TEdit; ButtonAffPort: TButton; + GroupBox2: TGroupBox; + CheckDebugAnalyse: TCheckBox; + CheckDebugBranches: TCheckBox; + GroupBox3: TGroupBox; + ButtonImporter: TButton; + RadioGroup1: TRadioGroup; + RadioCroisSuite: TRadioButton; + RadioCroisBase: TRadioButton; + EditBaseCrois: TEdit; procedure FormResize(Sender: TObject); procedure CheckSegmentsClick(Sender: TObject); procedure CheckConnexionsClick(Sender: TObject); @@ -30,15 +39,25 @@ type procedure TrackBar1Change(Sender: TObject); procedure ButtonAffPortClick(Sender: TObject); procedure FormCreate(Sender: TObject); + procedure ButtonImporterClick(Sender: TObject); + procedure CheckDebugAnalyseClick(Sender: TObject); + procedure CheckDebugBranchesClick(Sender: TObject); + procedure EditBaseCroisChange(Sender: TObject); + procedure CheckPortsClick(Sender: TObject); private { Déclarations privées } public { Déclarations publiques } end; + Trec_cdm = record adresse : integer; + distance : integer; // distance au port d'entrée + end; + tDetect_cdm= array[1..max_db] of Trec_cdm; + TAig_CDM = record - adresse,temps : integer; - modele : TEquipement ; + adresse,adrtriple,temps : integer; + modele : TEquipement ; ADroit : integer ; // (TJD:identifiant extérieur) connecté sur la position droite en talon ADroitB : char ; // P D S Z @@ -110,13 +129,15 @@ type var Segment : array of Tsegment; - nInter,nPeriph,nSeg,nPort,nligne,XminiCDM,XmaxiCDM,YminiCDM,YmaxiCDM,NAig_CDM : integer; + nInter,nPeriph,nSeg,nPort,nligne,XminiCDM,XmaxiCDM,YminiCDM,YmaxiCDM,NAig_CDM,Ndet_CDM, + DernAdrAig,BaseCroisement,SeqAdrCroisement,nb_det : integer; lignes : TStrings; reducX,reducY : double; FormAnalyseCDM: TFormAnalyseCDM; - NomModule : string; - + NomModule,sBranche : string; + debugBranche,debugAnalyse : boolean; Aig_CDM : array[0..NbreMaxiAiguillages] of TAig_CDM; + Det_CDM : array[1..500] of integer; procedure Analyse_seg; @@ -124,27 +145,35 @@ implementation {$R *.dfm} +// cherche, isole et restreint la chaine s qui contient "chercher" function isole_valeur(var s : string; chercher : string) : string; var i : integer; + serr : string; begin - i:=pos(chercher,s); - if i=0 then begin Affiche('Erreur : pas de chaine '+chercher+' dans '+s,clred);exit;end; - delete(s,1,i+length(chercher)-1); + i:=pos(chercher,s); + if i=0 then begin + serr:='Erreur : pas de chaine '+chercher+' dans "'+s+'" Segment '+intToSTR(segment[nSeg-1].numero); + Affiche(serr,clred); + AfficheDebug(serr,clred); + isole_valeur:=''; + exit; + end; + delete(s,1,i+length(chercher)-1); - repeat - if s[1]=' ' then delete(s,1,1); - until (s[1]<>' ') or (length(s)=0); + repeat + if s[1]=' ' then delete(s,1,1); + until (s[1]<>' ') or (length(s)=0); - i:=pos(' ',s); - if i<>0 then isole_valeur:=copy(s,1,i-1) else isole_valeur:=s; + i:=pos(' ',s); + if i<>0 then isole_valeur:=copy(s,1,i-1) else isole_valeur:=s; end; procedure compile_periph; -var i,erreur : integer; +var i,j,erreur : integer; s,s2: string; + trouve : boolean; begin - //------------------------Lecture periph---------------------------- - + //------------------------Lecture periph---------------------------- inc(nPeriph); segment[nSeg-1].nPeriph:=nPeriph; setlength(segment[nSeg-1].Periph,nPeriph); @@ -201,6 +230,20 @@ begin s2:=isole_valeur(s,'address'); val(s2,i,erreur); Segment[nSeg-1].periph[nperiph-1].Adresse:=i; + if (Segment[nSeg-1].periph[nperiph-1].typ='detector') and (i<>0) then + begin + // remplit le tableau des détecteurs cdm + trouve:=false; + for j:=1 to nDet_cdm do + begin + trouve:=Det_cdm[j]=i; // si déja stocké + end; + if not(trouve) then + begin + inc(nDet_cdm); + Det_CDM[nDet_cdm]:=i; + end; + end; s2:=isole_valeur(s,'status'); val(s2,i,erreur); @@ -239,7 +282,6 @@ begin s2:=isole_valeur(s,'z='); val(s2,i,erreur); Segment[nSeg-1].inter[nInter-1].MirrorZ:=i; - end; procedure compile_port; @@ -268,6 +310,7 @@ begin Segment[nSeg-1].port[nPort-1].local:=i; inc(nligne,2); + s:=AnsiLowerCase(lignes[nligne]); s2:=isole_valeur(s,'x='); val(s2,i,erreur); @@ -306,7 +349,7 @@ end; procedure compile_segment; var i,erreur : integer; - s,s2,segType: string; + s,s2,segType,serr: string; begin //------------------------Lecture segment---------------------------- nport:=0; @@ -320,13 +363,19 @@ begin Segment[nSeg-1].nInter:=0; s:=AnsiLowerCase(lignes[nligne]); i:=pos('#',s); - if i=0 then begin Affiche('Erreur structure n°2',clOrange);exit;end; + if i=0 then + begin + serr:='Erreur structure n°2'; + Affiche(serr,clOrange); + AfficheDebug(serr,clOrange); + exit; + end; delete(s,1,i); val(s,i,erreur); segment[nSeg-1].numero:=i; if debugAnalyse then AfficheDebug('Compile segment '+intToSTR(i),claqua); - + delete(s,1,erreur); s2:=isole_valeur(s,'obj type: '); @@ -388,11 +437,11 @@ begin s2:=isole_valeur(s,'length:'); val(s2,i,erreur); segment[nSeg-1].longueur:=i; - s2:=isole_valeur(s,'lengthdev:'); + s2:=isole_valeur(s,'lengthdev'); val(s2,i,erreur); segment[nSeg-1].lengthdev:=i; - inc(nligne); + inc(nligne,2); // 1 ligne vide s:=AnsiLowerCase(lignes[nligne]); s2:=isole_valeur(s,'xc0:'); val(s2,i,erreur); @@ -417,13 +466,20 @@ begin s2:=isole_valeur(s,'adresse ='); val(s2,i,erreur); segment[nSeg-1].adresse:=i; + if i=0 then + begin + Affiche('Aiguillage segment '+intToSTR(segment[nSeg-1].numero)+' adresse nulle',clred); + AfficheDebug('Aiguillage segment '+intToSTR(segment[nSeg-1].numero)+' adresse nulle',clred); + end; + if i>DernAdrAig then DernAdrAig:=i; - if (segType='dbl_slip_switch') then + if (segType='dbl_slip_switch') or (segType='turnout_3way') then begin s:=AnsiLowerCase(lignes[nligne]); s2:=isole_valeur(s,'adresse2 ='); val(s2,i,erreur); segment[nSeg-1].adresse2:=i; + if i>DernAdrAig then DernAdrAig:=i; end; s2:=isole_valeur(s,'duree ='); @@ -476,7 +532,6 @@ begin end; //turnout_3way - if segType='turnout_sym' then begin s2:=isole_valeur(s,'radius:'); @@ -505,12 +560,14 @@ begin s2:=isole_valeur(s,'adresse ='); val(s2,i,erreur); segment[nSeg-1].adresse:=i; + if i>DernAdrAig then DernAdrAig:=i; + s2:=isole_valeur(s,'duree ='); val(s2,i,erreur); segment[nSeg-1].duree:=i; exit; end; - + if segType='turnout_curved_2r' then begin inc(nligne); @@ -532,7 +589,7 @@ begin segment[nSeg-1].angle:=i; inc(nligne); - s:=AnsiLowerCase(lignes[nligne]); + s:=AnsiLowerCase(lignes[nligne]); s2:=isole_valeur(s,'length:'); val(s2,i,erreur); segment[nSeg-1].longueur:=i; @@ -560,10 +617,27 @@ begin s2:=isole_valeur(s,'yc:'); val(s2,i,erreur); segment[nSeg-1].yc:=i; + + inc(nligne); + s:=AnsiLowerCase(lignes[nligne]); + + s2:=isole_valeur(s,'adresse ='); + val(s2,i,erreur); + if i>DernAdrAig then DernAdrAig:=i; + + segment[nSeg-1].adresse:=i; + s2:=isole_valeur(s,'duree ='); + val(s2,i,erreur); + segment[nSeg-1].duree:=i; exit; end; - + if segType='dbl_cross_over' then + begin + Affiche('Bretelle double jonction non gérée',clred); + AfficheDebug('Bretelle double jonction non gérée',clred); + end; + if segType='turnout_curved' then begin @@ -615,6 +689,8 @@ begin s2:=isole_valeur(s,'adresse ='); val(s2,i,erreur); segment[nSeg-1].adresse:=i; + if i>DernAdrAig then DernAdrAig:=i; + s2:=isole_valeur(s,'duree ='); val(s2,i,erreur); segment[nSeg-1].duree:=i; @@ -648,7 +724,7 @@ begin segment[nSeg-1].CurveOffset:=i; end; - if segment[nseg-1].typ='arc' then + if (SegType='arc') or (Segtype='curve') then begin s2:=isole_valeur(s,'lxc:'); val(s2,i,erreur); @@ -673,22 +749,26 @@ begin end; procedure D_Arc(Canvas: TCanvas; CenterX,CenterY: integer; - Radius: Integer; StartDegrees, StopDegrees: Double); - //Get it in http://delphidabbler.com/tips/148 -const - Offset = 90; + Radius: Integer; StartDegres, StopDegres: Double); +const pisur180 =pi/180 ; var - X1, X2, X3, X4: Integer; - Y1, Y2, Y3, Y4: Integer; + X1,X2,X3,X4: Integer; + Y1,Y2,Y3,Y4: Integer; + ech : double; begin - X1 := CenterX - Radius; - Y1 := CenterY - Radius; - X2 := CenterX + Radius; - Y2 := CenterY + Radius; - X4 := CenterX + Round(Radius * Cos(DegToRad(Offset + StartDegrees))); - Y4 := Centery - Round(Radius * Sin(DegToRad(Offset + StartDegrees))); - X3 := CenterX + Round(Radius * Cos(DegToRad(Offset + StopDegrees))); - Y3 := Centery - Round(Radius * Sin(DegToRad(Offset + StopDegrees))); + if StopDegres<0 then setArcDirection(Canvas.Handle,AD_COUNTERCLOCKWISE) + else setArcDirection(Canvas.Handle,AD_CLOCKWISE); + + StartDegres:=startDegres; + stopDegres:=StartDegres+stopDegres; + X1:=CenterX - Radius; + Y1:=CenterY - Radius; + X2:=CenterX + Radius; + Y2:=CenterY + Radius; + X4:=CenterX + Round(Radius * Cos(StartDegres*pisur180)); + Y4:=Centery - Round(Radius * Sin(StartDegres*pisur180)); + X3:=CenterX + Round(Radius * Cos(StopDegres*pisur180)); + Y3:=Centery - Round(Radius * Sin(StopDegres*pisur180)); Canvas.Arc(X1, Y1, X2, Y2, X3, Y3, X4, Y4); end; @@ -708,13 +788,20 @@ begin end; end; +procedure angle_cdm(centreX,centreY:integer;debut,fin : double ;rayon : integer); +var ech : double; +begin + coords(centreX,centreY); + rayon:=round(rayon*reducX); + D_arc(FormAnalyseCDM.ImageCDM.Canvas,centreX,centreY,rayon,debut,fin); +end; + procedure affichage; var r : Trect; - i,j,x1,x2,y1,y2,largeur,hauteur,cx,cy,rayon : integer; - startAngle,arcAngle,lxc,lyc : integer; + i,j,x1,x2,y1,y2,largeur,hauteur,rayon,centreX,centreY,Numsegment : integer; SegType,s,s2 : string; - Zoom : double; - portsSeg : array[0..10] of record x,y : integer; end; + Ech,Zoom,startAngle,StopAngle,AncienStart : double; + portsSeg : array[0..40] of record x,y : integer; end; begin if (xMaxiCDM-xminiCDM=0) or (yMaxiCDM-yminiCDM=0) then exit; with formAnalyseCDM do @@ -745,7 +832,8 @@ begin Zoom:=(270-formAnalyseCDM.TrackBar1.Position)/100; reducX:=Zoom*(largeur-2*cadre)/(XmaxiCDM-XminiCDM); - reducY:=Zoom*(hauteur-2*cadre)/(YmaxiCDM-YminiCDM); + reducY:=reducX; + //reducY:=Zoom*(hauteur-2*cadre)/(YmaxiCDM-YminiCDM); with FormAnalyseCDM.ImageCDM.Canvas do begin @@ -766,6 +854,7 @@ begin for i:=0 to nSeg-1 do begin SegType:=Segment[i].typ; + NumSegment:=Segment[i].numero; FormAnalyseCDM.ImageCDM.Canvas.Pen.Color:=claqua; FormAnalyseCDM.ImageCDM.Canvas.Font.Color:=claqua; @@ -804,7 +893,7 @@ begin //Affiche_port(i,j); //s:='Port '+intToSTR(Segment[i].port[j].numero)+' '+Segment[i].port[j].typ; - s:='P'+intToSTR(Segment[i].port[j].numero); + s:='S'+intToSTR(NumSegment)+'P'+intToSTR(Segment[i].port[j].numero); x1:=segment[i].port[j].X; y1:=segment[i].port[j].y; with FormAnalyseCDM.ImageCDM.Canvas do @@ -812,35 +901,103 @@ begin //Affiche('I='+intToSTR(i)+' '+intToSTR(x1)+' '+intToSTR(y1),clred); coords(x1,y1); if formAnalyseCDM.CheckConnexions.checked then Ellipse(x1-5,y1-5,x1+5,y1+5); - portsSeg[j].x:=x1; - portsSeg[j].y:=y1; + if j<40 then + begin + portsSeg[j].x:=x1; + portsSeg[j].y:=y1; + end; if formAnalyseCDM.CheckPorts.checked then Textout(x1,y1,s); end; //Affiche(s,ClYellow); end; - // relier les ports en vert &&& - if formAnalyseCDM.CheckPorts.checked then + + // relier les ports en vert + //if formAnalyseCDM.CheckPorts.checked then with FormAnalyseCDM.ImageCDM.Canvas do begin - moveto(portsSeg[0].x,portsSeg[0].y); - for j:=1 to nPort-1 do - LineTo(portsSeg[j].x,portsSeg[j].y); - { if segment[i].typ='arc' then - begin // D_Arc(Canvas: TCanvas; CenterX,CenterY: integer;Radius: Integer; StartDegrees, StopDegrees: Double); + pen.width:=2; + if (segtype='crossing') or (segType='dbl_slip_switch') then + begin + moveto(portsSeg[0].x,portsSeg[0].y); + LineTo(portsSeg[2].x,portsSeg[2].y); + moveto(portsSeg[1].x,portsSeg[1].y); + LineTo(portsSeg[3].x,portsSeg[3].y); + if formAnalyseCDM.CheckAdresses.checked then + begin + s:='A'+intToSTR(Segment[i].adresse); + x1:=(portsSeg[0].x+portsSeg[1].x) div 2; + y1:=(portsSeg[0].y+portsSeg[1].y) div 2; + Textout(x1,y1,s); + x1:=Segment[i].adresse2; + if x1<>0 then + begin + s:='A'+intToSTR(Segment[i].adresse2); + x1:=(portsSeg[1].x+portsSeg[3].x) div 2; + y1:=(portsSeg[1].y+portsSeg[3].y) div 2; + Textout(x1,y1,s); + end; + end; + end + else + if segtype='turnout' then + begin + moveto(portsSeg[0].x,portsSeg[0].y); + LineTo(portsSeg[1].x,portsSeg[1].y); + moveTo((portsSeg[0].x+portsSeg[1].x)div 2,(portsSeg[0].y+portsSeg[1].y)div 2); + LineTo(portsSeg[2].x,portsSeg[2].y); + if formAnalyseCDM.CheckAdresses.checked then + begin + s:='A'+intToSTR(Segment[i].adresse); + x1:=(portsSeg[0].x+portsSeg[1].x) div 2; + y1:=(portsSeg[0].y+portsSeg[1].y) div 2; + Textout(x1,y1,s); + end; + end + else + if (segtype='turnout_curved') or (segtype='turnout_curved_2r') + then + begin + moveto(portsSeg[0].x,portsSeg[0].y); + LineTo(portsSeg[1].x,portsSeg[1].y); + moveTo((portsSeg[0].x+portsSeg[1].x)div 2,(portsSeg[0].y+portsSeg[1].y)div 2); + LineTo(portsSeg[2].x,portsSeg[2].y); + begin + s:='A'+intToSTR(Segment[i].adresse); + x1:=(portsSeg[0].x+portsSeg[1].x) div 2; + y1:=(portsSeg[0].y+portsSeg[1].y) div 2; + Textout(x1,y1,s); + end; + { rayon:=segment[i].Rayon; + StartAngle:=(segment[i].StartAngle/100); + StopAngle:=segment[i].ArcAngle/100; + centreX:=segment[i].xc0; + CentreY:=segment[i].yc0; + angle_cdm(centreX,CentreY,startangle,stopangle,rayon); } + end + else + if (segType='arc') or (segType='curve') then + begin rayon:=segment[i].Rayon; - StartAngle:=segment[i].StartAngle; - ArcAngle:=segment[i].ArcAngle; - lxc:=segment[i].lXc;lyc:=segment[i].lyc; - coords(lxc,lyc); - D_arc(FormAnalyseCDM.ImageCDM.Canvas,lxc,lyc,rayon,startAngle,ArcAngle); - end; } + StartAngle:=(segment[i].StartAngle/100); + StopAngle:=segment[i].ArcAngle/100; + centreX:=segment[i].lXc; + CentreY:=segment[i].lyc; + angle_cdm(centreX,CentreY,startangle,stopangle,rayon); + end + else + begin + moveto(portsSeg[0].x,portsSeg[0].y); + for j:=1 to nPort-1 do + LineTo(portsSeg[j].x,portsSeg[j].y); + AncienStart:=portsSeg[j].x; + end; + end; // périphériques en jaune -------------------------- nperiph:=Segment[i].nperiph; FormAnalyseCDM.ImageCDM.Canvas.Pen.Color:=clYellow; FormAnalyseCDM.ImageCDM.Canvas.Font.Color:=clYellow; - //nperiph:=0; //&&& for j:=0 to nPeriph-1 do begin @@ -852,7 +1009,11 @@ begin begin coords(x1,y1); if formAnalyseCDM.CheckConnexions.checked then Ellipse(x1-5,y1-5,x1+5,y1+5); - if formAnalyseCDM.CheckAdresses.checked then textout(x1,y1,s2); + if formAnalyseCDM.CheckAdresses.checked then + begin + if segment[i].periph[j].typ='detector' then font.Color:=clAqua else font.Color:=clorange; + textout(x1,y1,s2); + end; end; //Affiche(s,clOrange); end; @@ -899,14 +1060,110 @@ begin end; end; -procedure trouve_IndexSegPort(seg,port : integer;var indexSeg,indexPort : integer); +function segment_aig(s : string) : boolean; +begin + segment_aig:=(s='turnout') or (s='dbl_slip_switch') or (s='turnout_sym') or + (s='turnout_curved') or (s='turnout_curved_2r') or (s='turnout_3way'); +end; + +// trouve l'index du segment contenant l'aiguillage adresse +function trouve_IdSegment_aig(adresse : integer;var Id: integer) : boolean; +var i,p,p2 : integer; + trouve : boolean; +begin + i:=0; + repeat + p:=segment[i].adresse; + p2:=segment[i].adresse2; + //Affiche(intToSTR(p),clwhite); + trouve:=((p=adresse) or (p2=adresse)) and segment_aig(segment[i].typ); + inc(i); + until (i>nSeg-1) or trouve; + dec(i); + if trouve then + begin + Id:=i; + trouve_IdSegment_Aig:=true; + end + else + begin + id:=-1; + trouve_IdSegment_Aig:=false; + end +end; + + +// trouve les indexs Segment et port le détecteur est detecteur +function trouve_IndexSegPortDetecteur(detecteur : integer;var indexSeg,indexPeriph : integer) : boolean; +var i,j,p,np : integer; + trouve : boolean; +begin + i:=0; + trouve:=false; + repeat + j:=0; + np:=segment[i].nperiph; // nombre de périphériques + repeat + if np>0 then + begin + p:=segment[i].periph[j].adresse; + //Affiche(intToSTR(p),clwhite); + trouve:=(p=detecteur); + end; + inc(j); + until (j>np-1) or trouve; + inc(i); + until (i>nSeg-1) or trouve; + dec(i);dec(j); + if trouve then + begin + trouve_IndexSegPortDetecteur:=true; + indexSeg:=i; + indexPeriph:=j; + end + else + begin + trouve_IndexSegPortDetecteur:=false; + indexSeg:=-1; + indexPeriph:=-1; + end +end; + +// trouve l'index du segment +function Index_Segment(seg : integer;var indexSeg : integer) : boolean; +var i,s : integer; + trouve : boolean; +begin + i:=0; + repeat + s:=segment[i].numero; + //Affiche(intToSTR(p),clwhite); + trouve:=(s=seg); + inc(i); + until (i>nSeg-1) or trouve; + dec(i); + if trouve then + begin + indexSeg:=i; + Index_Segment:=true; + end + else + begin + indexSeg:=-1; + Index_Segment:=false; + end +end; + + +// trouve les indexs du segment,port +function trouve_IndexSegPort(seg,port : integer;var indexSeg,indexPort : integer) : boolean; var i,j,p,np,ns : integer; trouve : boolean; begin i:=0; repeat j:=0; - np:=segment[i].nport; + np:=segment[i].nport; // nombre de ports ns:=segment[i].numero; repeat p:=segment[i].port[j].numero; @@ -921,24 +1178,40 @@ begin begin indexSeg:=i; indexPort:=j; + trouve_IndexSegPort:=true; end else begin + trouve_IndexSegPort:=false; indexSeg:=-1; indexPort:=-1; end end; -// trouve les index du port +// trouve l'index d'un port dans un segment +function trouve_IndexPort_Segment(IndexSegment,port : integer) : integer; +var i,np : integer; + trouve : boolean; +begin + np:=segment[indexSegment].nport; // nombre de ports + i:=0; + repeat + trouve:=segment[indexsegment].port[i].numero=port; + inc(i); + until (i>np-1) or trouve; + dec(i); + result:=i; +end; + +// trouve les index du port dans la liste des segments procedure trouve_IndexPort(port : integer;var indexSeg,indexPort : integer); -var i,j,p,np,ns : integer; +var i,j,p,np : integer; trouve : boolean; begin i:=0; repeat j:=0; np:=segment[i].nport; - ns:=segment[i].numero; repeat p:=segment[i].port[j].numero; //Affiche(intToSTR(p),clwhite); @@ -960,22 +1233,53 @@ begin end end; -function segment_aig(s : string) : boolean; +// raz du tableau des détecteurs rencontrés entre 2 aiguillages +procedure raz_detect(var t : tdetect_cdm); +var i : integer; begin - segment_aig:=(s='turnout') or (s='dbl_slip_switch') or (s='turnout_sym') or - (s='turnout_curved') or (s='turnout_curved_2r') or (s='turnout_3way'); + nb_det:=0; + for i:=1 to max_db do + begin + t[i].distance:=0;t[i].adresse:=0; + end; end; -// explore le port,segment jusqu'a trouver une adresse d'aiguillage ou de détecteur -function explore_port(seg,port : integer;var c : string) : integer; -var ns,i,IdSeg,IdPort,np,adresse,port1,port2,portSuivant,segSuivant,portLocal,portLocSuiv : integer; - typeP : string; - trouve : boolean; +// trie le tableau en fonction de la distance +procedure trier(var t : tdetect_cdm;n :integer); +var i,j : integer; + temp : trec_cdm; begin + for i:=1 to n do + begin + for j:=i+1 to n do + begin + if t[i].distance>t[j].distance then + begin + temp:=t[i]; + t[i]:=t[j]; + t[j]:=temp; + end; + end; + end; +end; + + +// fonction récursive +// explore le port,segment jusqu'a trouver une adresse d'aiguillage, de croisement, ou de détecteur +// renvoie l'adresse de l'aiguillage ou du détecteur et dans C le port (P D S) +function explore_port(seg,port : integer;var c : string) : integer; +var i,j,IdSeg,IdPort,NombrePeriph,port1,port2,portSuivant,segSuivant,portLocal, + xp,yp,xd,yd,detect,nb_det : integer; + typeP,serr : string; + sdetect : Tdetect_cdm; +begin + if seg=0 then exit; // laisser sinon mauvais transfert de variable dans la pile dans l'itération suivante!! trouve_IndexSegPort(seg,port,idSeg,IdPort); if idseg=-1 then begin - Affiche('Erreur 1 pas trouvé le port '+intToSTR(port),clred); + serr:='Erreur 1 pas trouvé le port '+intToSTR(port)+' dans la liste des segments'; + Affiche(serr,clred); + AfficheDebug(serr,clred); explore_port:=0; c:=''; exit; @@ -988,7 +1292,9 @@ begin //Affiche('segsuiv='+intToSTr(segsuivant),clred); if idSeg=-1 then begin - Affiche('Erreur 2 pas trouvé le port '+intToSTR(port),clred); + serr:='Erreur 2 pas trouvé le port '+intToSTR(port)+' dans la liste des segments'; + Affiche(serr,clred); + AfficheDebug(serr,clred); c:=''; explore_port:=0; exit; @@ -997,6 +1303,20 @@ begin // remonter au segment pour voir si c'est un aiguillage typeP:=segment[idSeg].typ; + + if typeP='dbl_slip_switch' then + begin + portlocal:=segment[idSeg].port[idport].local; + case portlocal of + 0 : c:='D'; + 1 : c:='S'; + 2 : c:='D'; + 3 : c:='S'; + end; + explore_port:=segment[idSeg].adresse; + exit; + end; + if segment_aig(typeP) then // est-ce un aig //------------- aiguillage begin @@ -1012,43 +1332,62 @@ begin // --- croisement if typeP='crossing' then begin - portLocal:=segment[idSeg].port[idport].local; // port local - // port d'en face - case portLocal of - 0 : portLocSuiv:=2; - 1 : portLocSuiv:=3; - 2 : portLocSuiv:=0; - 3 : portLocSuiv:=1; + portlocal:=segment[idSeg].port[idport].local; + case portlocal of + 0 : c:='D'; + 1 : c:='S'; + 2 : c:='D'; + 3 : c:='S'; end; - i:=explore_port(segSuivant,segment[idSeg].port[PortLocSuiv].numero,c); - explore_port:=i; + explore_port:=segment[idSeg].adresse; exit; end; - // y a t-il des periph - np:=segment[idSeg].nperiph; - if np<>0 then + // trouver le détecteur le plus proche. + NombrePeriph:=segment[idSeg].nperiph; + j:=0;detect:=0;nb_det:=0; + if NombrePeriph<>0 then begin - // présence de péripéhiques - i:=0; + raz_detect(sDetect); // on peut rencontrer des détecteurs non appairés: ex ; 514 522 514 522 repeat - typeP:=segment[idSeg].periph[i].typ; - adresse:=segment[idSeg].periph[i].adresse; - trouve:=(typeP='detector') and (adresse<>0); - inc(i); - until (i>np-1) or trouve; - if trouve then + if segment[idSeg].periph[j].typ='detector' then + begin + detect:=segment[idSeg].periph[j].adresse; + if detect<>0 then + begin + //if NivDebug=3 then Affichedebug('Détecteur '+inttoStr(detect),clyellow); + // incrémenter le compteur du détecteur rencontré + inc(nb_det); + sDetect[nb_det].adresse:=detect ; + // coordonnées du port + xp:=segment[idSeg].Port[idPort].x; + yp:=segment[idSeg].Port[idPort].y; + // coordonnées du détecteur + xd:=segment[idSeg].periph[j].x; + yd:=segment[idSeg].periph[j].y; + // calculer la distance du détecteur au port + sDetect[nb_det].distance:=round( sqrt( sqr(xp-xd)+sqr(yp-yd) )); + end; + end; + inc(j); + until (j>NombrePeriph-1) ; + // trier les détecteurs du segment dans l'ordre de la distance de la plus + // courte à la plus grande au port + if nb_det<>0 then begin + trier(Sdetect,nb_det); + + // on prend le premier!! + explore_port:=sDetect[1].adresse; c:=''; - explore_port:=adresse; exit; end; end; // trouver l'autre port du segment idseg // sur 2 ports - np:=segment[idSeg].nport; - if np=0 then + NombrePeriph:=segment[idSeg].nport; + if NombrePeriph=0 then begin c:=''; explore_port:=0; @@ -1057,13 +1396,12 @@ begin port1:=segment[idSeg].port[0].numero; port2:=segment[idSeg].port[1].numero; i:=0; - if (port1<>portSuivant) and (segment[idSeg].port[0].connecte) then i:=explore_port(SegSuivant,port1,c); + if (port1<>portSuivant) and (segment[idSeg].port[0].connecte) then i:=explore_port(SegSuivant,port1,c); if (port2<>portSuivant) and (segment[idSeg].port[1].connecte) then i:=explore_port(SegSuivant,port2,c); + explore_port:=i; exit; - - typeP:=segment[idSeg].typ; // explorer l'autre port if (typeP='straight') or (typeP='arc') or (typeP='curve') or (typeP='pre_curve') then @@ -1083,169 +1421,44 @@ begin end; -procedure cree; - var i,j,connecteAuPort,ConnecteAuSeg,numPort,NumSegment,IndexSegment,IndexPort, - nport,adresse,adresse2,element,DernAdrAig : integer; - s,segType,c : string; +// stocke les aiguillages et les croisement dans le tableau Aig_CDM +procedure remplit_Aig_cdm; + var i,j,NumSegment,IndexSegment,IndexPort, + adresse,adresse2,element,AdrCroisement : integer; + s,segType,c,serr : string; begin // 1er segment, 1er port IndexSegment:=0;IndexPort:=0; - - { - for i:=1 to 10 do - begin - numSegment:=segment[IndexSegment].numero; - NumPort:=segment[IndexSegment].port[IndexPort].numero; - connecteAuPort:=segment[IndexSegment].port[IndexPort].ConnecteAuPort; - connecteAuSeg:=segment[IndexSegment].port[IndexPort].ConnecteAuSeg; - Affiche('le segment '+intToSTR(NumSegment)+' port '+intToSTR(NumPort)+' est connecté au S'+intToSTR(connecteAUSeg)+' P'+intToSTR(connecteAuPort),clyellow); - trouve_IndexSegPort(connecteAuPort,IndexSegment,IndexPort); - end; - } - - DernAdrAig:=0; - // liste les segments avec des aiguillages - if debugAnalyse then - begin - AfficheDebug('Liste des aiguillages',clWhite); - AfficheDebug('--------------------------------',clWhite); - end; - NAig_CDM:=0; - for i:=0 to nseg-1 do - begin - segType:=segment[i].typ; - if segment_aig(segtype) then - begin - numSegment:=segment[i].numero; - adresse:=segment[i].adresse; - if DernAdrAig0 then - begin - inc(nAig_CDM); // attention deux adresses!! - // remplissage 2eme adresse - Aig_CDM[nAig_CDM].adresse:=adresse2; - Aig_CDM[nAig_CDM].temps:=segment[i].duree; - Aig_CDM[nAig_CDM].modele:=tjd; - Aig_CDM[nAig_CDM].ddroit:=Adresse; - Aig_CDM[nAig_CDM].ddroitB:='D'; - Aig_CDM[nAig_CDM].dDevie:=Adresse; - Aig_CDM[nAig_CDM].dDevieB:='S'; - Aig_CDM[nAig_CDM].etatTJD:=4; - end; - - end; - - if (SegType='turnout') or (SegType='turnout_sym') or (SegType='turnout_curved') or (SegType='turnout_curved_2r') then Aig_CDM[nAig_CDM].modele:=aig; - if (SegType='turnout_3way') then Aig_CDM[nAig_CDM].modele:=triple; - - for j:=0 to segment[i].nport-1 do - begin - s:=' Port '+intToSTR(j)+' '; - if (SegType<>'dbl_slip_switch') and (Segtype<>'turnout_3way') then - case j of - 0 : s:=s+'P'; - 1 : s:=s+'D'; - 2 : s:=s+'S'; - end; - - if (SegType='dbl_slip_switch') then - begin - - case j of - 0 : s:=s+'D'; - 1 : s:=s+'S'; - 2 : s:=s+'D'; - 3 : s:=s+'S'; - end; - end; - - if (SegType='turnout_3way') then - case j of - 0 : s:=s+'P'; - 1 : s:=s+'D'; - 2 : s:=s+'S'; - 3 : s:=s+'S2'; - end; - - // explorer les ports de l'aiguillage - element:=explore_port(numsegment,segment[i].port[j].numero,c); - s:=s+' Element : '+intToStr(element)+c; - if debugAnalyse then AfficheDebug(s,clorange); - - if (SegType='dbl_slip_switch') then - begin - if j=0 then begin Aig_CDM[nAig_CDM-1].Adroit:=element;if length(c)<>0 then Aig_CDM[nAig_CDM-1].AdroitB:=c[1];end; - if j=1 then begin Aig_CDM[nAig_CDM-1].Adevie:=element;if length(c)<>0 then Aig_CDM[nAig_CDM-1].AdevieB:=c[1];end; - if j=2 then begin Aig_CDM[nAig_CDM].Adroit:=element;if length(c)<>0 then Aig_CDM[nAig_CDM].AdroitB:=c[1];end; - if j=3 then begin Aig_CDM[nAig_CDM].Adevie:=element;if length(c)<>0 then Aig_CDM[nAig_CDM].AdevieB:=c[1];end; - end - else - begin - // autre aiguillage que tjd (3 ou 4 ports pour les tri) - if j=0 then begin Aig_CDM[nAig_CDM].APointe:=element;if length(c)<>0 then Aig_CDM[nAig_CDM].APointeB:=c[1];end; - if j=1 then begin Aig_CDM[nAig_CDM].ADroit:=element; if length(c)<>0 then Aig_CDM[nAig_CDM].ADroitB:=c[1];end; - if j=2 then begin Aig_CDM[nAig_CDM].ADevie:=element; if length(c)<>0 then Aig_CDM[nAig_CDM].ADevieB:=c[1];end; - if j=3 then begin Aig_CDM[nAig_CDM].ADevie:=element; if length(c)<>0 then Aig_CDM[nAig_CDM].ADevieB:=c[1];end; - end - end; - // exit; - end; - end; - if debugAnalyse then begin AfficheDebug(' ',clwhite); AfficheDebug('Liste des croisements',clWhite); AfficheDebug('--------------------------------',clWhite); end; + NAig_CDM:=0; + SeqAdrCroisement:=0; + inc(DernAdrAig); for i:=0 to nseg-1 do begin segType:=segment[i].typ; if segType='crossing' then begin numSegment:=segment[i].numero; - adresse:=segment[i].adresse; + if formAnalyseCDM.radioCroisSuite.checked then AdrCroisement:=DernAdrAig+SeqAdrCroisement; + if formAnalyseCDM.radioCroisBase.checked then AdrCroisement:=BaseCroisement+SeqAdrCroisement; + segment[i].adresse:=AdrCroisement; inc(nAig_CDM); - inc(dernAdrAig); - Aig_CDM[nAig_CDM].adresse:=DernAdrAig; //&&&& - + Aig_CDM[nAig_CDM].adresse:=AdrCroisement; Aig_CDM[nAig_CDM].modele:=crois; - s:='Segment '+intToSTR(numSegment)+' type='+segtype+' Adresse='+intToSTR(DernAdrAig); + s:='Segment '+intToSTR(numSegment)+' type='+segtype+' Adresse='+intToSTR(AdrCroisement); + inc(SeqAdrCroisement); if debugAnalyse then AfficheDebug(s,clorange); - for j:=0 to segment[i].nport-1 do begin s:=' Port '+intToSTR(j)+' '; - - // explorer les ports de l'aiguillage element:=explore_port(numsegment,segment[i].port[j].numero,c); @@ -1260,25 +1473,733 @@ begin if debugAnalyse then afficheDebug(s,clorange); end; + end; end; + if debugAnalyse then + begin + AfficheDebug('Liste des aiguillages',clWhite); + AfficheDebug('--------------------------------',clWhite); + end; + for i:=0 to nseg-1 do + begin + segType:=segment[i].typ; + if segment_aig(segtype) then + begin + numSegment:=segment[i].numero; + adresse:=segment[i].adresse; + if adresse<>0 then + begin + s:='Segment '+intToSTR(numSegment)+' type='+segtype+' Adresse='+intToSTR(adresse); + if segType='dbl_slip_switch' then s:=s+' Adresse2='+intToSTR(segment[i].adresse2); + if debugAnalyse then AfficheDebug(s,clorange); + if (adresse=0) then + begin + serr:=' Erreur segment aiguillage ('+segType+') avec adresse nulle ; segment '+intToSTR(numSegment); + Affiche(serr,clred); + afficheDebug(serr,clred); + end; + + + inc(nAig_CDM); + Aig_CDM[nAig_CDM].adresse:=adresse; + Aig_CDM[nAig_CDM].temps:=segment[i].duree; + + if (SegType='dbl_slip_switch') then + begin + adresse2:=segment[i].adresse2; + Aig_CDM[nAig_CDM].modele:=tjd; + Aig_CDM[nAig_CDM].ddroit:=Adresse2; + Aig_CDM[nAig_CDM].ddroitB:='D'; + Aig_CDM[nAig_CDM].dDevie:=Adresse2; + Aig_CDM[nAig_CDM].dDevieB:='S'; + + if adresse2=0 then + begin + Aig_CDM[nAig_CDM].etatTJD:=2; + end + else Aig_CDM[nAig_CDM].etatTJD:=4; + + if adresse2<>0 then + begin + inc(nAig_CDM); // attention deux adresses sur TJD 4 états + // remplissage 2eme adresse + Aig_CDM[nAig_CDM].adresse:=adresse2; + Aig_CDM[nAig_CDM].temps:=segment[i].duree; + Aig_CDM[nAig_CDM].modele:=tjd; + Aig_CDM[nAig_CDM].ddroit:=Adresse; + Aig_CDM[nAig_CDM].ddroitB:='D'; + Aig_CDM[nAig_CDM].dDevie:=Adresse; + Aig_CDM[nAig_CDM].dDevieB:='S'; + Aig_CDM[nAig_CDM].etatTJD:=4; + end; + + end; + + if (SegType='turnout') or (SegType='turnout_sym') or (SegType='turnout_curved') or (SegType='turnout_curved_2r') then Aig_CDM[nAig_CDM].modele:=aig; + if (SegType='turnout_3way') then + begin + Aig_CDM[nAig_CDM].modele:=triple; + Aig_CDM[nAig_CDM].adrTriple:=segment[i].adresse2; + end; + + // remplir les ports de connexion (aig et tjd) + for j:=0 to segment[i].nport-1 do + begin + s:=' Port '+intToSTR(j)+' '; + if (SegType<>'dbl_slip_switch') and (Segtype<>'turnout_3way') then + case j of + 0 : s:=s+'P'; + 1 : s:=s+'D'; + 2 : s:=s+'S'; + end; + + if (SegType='dbl_slip_switch') then //or (SegType='crossing') then + begin + case j of + 0 : s:=s+'D'; + 1 : s:=s+'S'; + 2 : s:=s+'D'; + 3 : s:=s+'S'; + end; + end; + + if (SegType='turnout_3way') then + case j of + 0 : s:=s+'P'; + 1 : s:=s+'D'; + 2 : s:=s+'S'; + 3 : s:=s+'S2'; + end; + + // explorer les ports de l'aiguillage + element:=explore_port(numsegment,segment[i].port[j].numero,c); + s:=s+' Element : '+intToStr(element)+c; + if debugAnalyse then AfficheDebug(s,clorange); + + if (SegType='dbl_slip_switch') then + begin + if adresse2<>0 then + begin + // 4 états + if j=0 then begin Aig_CDM[nAig_CDM-1].Adroit:=element;if length(c)<>0 then Aig_CDM[nAig_CDM-1].AdroitB:=c[1];end; + if j=1 then begin Aig_CDM[nAig_CDM-1].Adevie:=element;if length(c)<>0 then Aig_CDM[nAig_CDM-1].AdevieB:=c[1];end; + if j=2 then begin Aig_CDM[nAig_CDM].Adroit:=element;if length(c)<>0 then Aig_CDM[nAig_CDM].AdroitB:=c[1];end; + if j=3 then begin Aig_CDM[nAig_CDM].Adevie:=element;if length(c)<>0 then Aig_CDM[nAig_CDM].AdevieB:=c[1];end; + end + else + begin + // 2 états + if j=0 then begin Aig_CDM[nAig_CDM].Adroit:=element;if length(c)<>0 then Aig_CDM[nAig_CDM].AdroitB:=c[1];end; + if j=1 then begin Aig_CDM[nAig_CDM].Adevie:=element;if length(c)<>0 then Aig_CDM[nAig_CDM].AdevieB:=c[1];end; + if j=2 then begin Aig_CDM[nAig_CDM].Ddroit:=element;if length(c)<>0 then Aig_CDM[nAig_CDM].DdroitB:=c[1];end; + if j=3 then begin Aig_CDM[nAig_CDM].Ddevie:=element;if length(c)<>0 then Aig_CDM[nAig_CDM].DdevieB:=c[1];end; + end; + end; + + if SegType='turnout_3way' then + begin + if j=0 then begin Aig_CDM[nAig_CDM].APointe:=element;if length(c)<>0 then Aig_CDM[nAig_CDM].APointeB:=c[1];end; + if j=1 then begin Aig_CDM[nAig_CDM].ADroit:=element; if length(c)<>0 then Aig_CDM[nAig_CDM].ADroitB:=c[1];end; + if j=2 then begin Aig_CDM[nAig_CDM].ADevie:=element; if length(c)<>0 then Aig_CDM[nAig_CDM].ADevieB:=c[1];end; + if j=3 then begin Aig_CDM[nAig_CDM].ADevie2:=element; if length(c)<>0 then Aig_CDM[nAig_CDM].ADevie2B:=c[1];end; + end; + + if segType='crossing' then + begin + if j=0 then begin Aig_CDM[nAig_CDM].Adroit:=element;if length(c)<>0 then Aig_CDM[nAig_CDM].AdroitB:=c[1];end; + if j=1 then begin Aig_CDM[nAig_CDM].Adevie:=element;if length(c)<>0 then Aig_CDM[nAig_CDM].AdevieB:=c[1];end; + if j=2 then begin Aig_CDM[nAig_CDM].Ddroit:=element;if length(c)<>0 then Aig_CDM[nAig_CDM].DdroitB:=c[1];end; + if j=3 then begin Aig_CDM[nAig_CDM].Ddevie:=element;if length(c)<>0 then Aig_CDM[nAig_CDM].DdevieB:=c[1];end; + end; + + if (SegTYpe='turnout') or (SegType='turnout_curved') or (SegType='turnout_curved_2r') or (SegType='turnout_sym') then + begin + if j=0 then begin Aig_CDM[nAig_CDM].APointe:=element;if length(c)<>0 then Aig_CDM[nAig_CDM].APointeB:=c[1];end; + if j=1 then begin Aig_CDM[nAig_CDM].ADroit:=element; if length(c)<>0 then Aig_CDM[nAig_CDM].ADroitB:=c[1];end; + if j=2 then begin Aig_CDM[nAig_CDM].ADevie:=element; if length(c)<>0 then Aig_CDM[nAig_CDM].ADevieB:=c[1];end; + end; + end; + end; + end; + end; +end; + +// trouve le port de destination sur un segment en fonction du port d'origine 'port' +function trouve_port_suivant(IndexSeg,port : integer) : integer; +var ctype: string; + pOrg,pDest,p1,p2 : integer; + trouve : boolean; +begin + ctype:=segment[indexSeg].typ; + + if (ctype='crossing') or (ctype='dbl_slip_switch') then + begin + // déterminer le numéro du port d'origine + pOrg:=0; + repeat + trouve:=segment[indexSeg].port[pOrg].numero=port; + if not(trouve) then inc(pOrg); + until trouve or (pOrg>3); + if pOrg=0 then pDest:=2; // port origine, port destination + if pOrg=1 then pDest:=3; + if pOrg=2 then pDest:=0; + if pOrg=3 then pDest:=1; + trouve_port_suivant:=segment[indexSeg].port[pDest].numero; + exit; + end; + + // autre aiguillage + if segment_aig(ctype) then + begin + // déterminer le numéro du port d'origine + pOrg:=0; + repeat + trouve:=segment[indexSeg].port[pOrg].numero=port; + if not(trouve) then inc(pOrg); + until trouve or (pOrg>3); + if pOrg=0 then pDest:=1; // port origine, port destination : aiguillage en position droite + if pOrg=1 then pDest:=0; + if pOrg=2 then pDest:=0; + if pOrg=3 then pDest:=0; // si c'est un triple + trouve_port_suivant:=segment[indexSeg].port[pDest].numero; + exit; + end; + + if ctype='turntable' then + begin + // on repart d'où on vient + trouve_port_suivant:=port; + exit; + end; + + // si section simple + p1:=segment[indexSeg].port[0].numero; + p2:=segment[indexSeg].port[1].numero; + if p1=port then + begin + trouve_port_suivant:=p2; + end; + if p2=port then + begin + trouve_port_suivant:=p1; + exit; + end; +end; + +// trouve le segment suivant du segment index, opposé au port +// 170 seg=169 171 | 173 Seg=172 174 | +// exemple (169,171) => 172 173 +function trouve_seg_suivant(IndexSeg,Indexport : integer;var IndexSegSuiv,IndexportSuiv : integer) : boolean; +var PortSuiv,NumSegment,ips,SegSuiv,np : integer; + ctype : string; +begin + numSegment:=segment[indexSeg].numero; + numport:=segment[indexSeg].port[indexPort].numero; + if nivDebug=3 then AfficheDebug('trouve le seg suivant au '+intToSTR(numSegment)+' port '+intToSTR(numport),clyellow); + np:=segment[indexSeg].nport; + if np<2 then + begin + // valable uniquement sur un segment à au moins 2 ports + Affiche('Erreur recherche sur un segment '+intToSTR(segment[indexSeg].numero)+' <2 ports',clred); + trouve_seg_suivant:=false; + IndexSegSuiv:=-1; + indexportSuiv:=-1; + exit; + end; + + ctype:=segment[indexSeg].typ; + + SegSuiv:=segment[indexSeg].port[Indexport].ConnecteAuSeg; + PortSuiv:=segment[indexSeg].port[Indexport].ConnecteAuPort; + //trouver l'index du port du segment + if segment[indexSeg].port[Indexport].connecte then + begin + if trouve_IndexSegPort(segSuiv,portSuiv,indexSeg,ips) then + begin + IndexSegSuiv:=indexSeg; + IndexPortSuiv:=ips; + //portsuiv:=segment[indexSeg].port[indexport].numero; + result:=true; + exit; + end + else + begin + Affiche('Pas trouvé l''index du segment port: '+intToSTR(SegSuiv)+' '+intToSTR(portSuiv),clred); + AfficheDebug('Pas trouvé l''index du segment port: '+intToSTR(SegSuiv)+' '+intToSTR(portSuiv),clOrange); + result:=false; + end; + end + else + begin + afficheDebug('Port non connecté',clOrange); + result:=false; + end; end; -procedure Analyse_seg; -var s,s2,ch,SegType: string; - i,nombre,position : integer; + +// renvoie le dernier champ d'une chaine +// s='aa,bb,ccc,ddd,ee' : renvoie ee +function dernier_champ(s : string) : string; +var i,l : integer; begin + if s='' then + begin + result:=''; + exit; + end; + l:=length(s); + i:=l+1; + repeat + dec(i); + until (s[i]=',') or (i=1); + if s[i]=',' then + begin + result:=copy(s,i+1,l-i); + exit; + end; + result:=''; + exit; +end; + + +// créée la branche depuis un aiguillage dont un des ports est un détecteur +// indexSeg,port : index su segment et port de départ +// AdrAig : adresse de l'aiguillage qui a servi de départ +procedure cree_branche_aig(indexSeg,Indexport,adrAig,NbreMaxiAigRencontres : integer); +var i,j,k,naig,IndexportSuivant,indexSegSuivant,NombrePeriph, + detecteur,indexElBranche,AdrAigRencontre,numSegment, + rien,erreur,det2,nb_det,xp,yp,xd,yd : integer; + trouve,sort : boolean; + s,ss,ss2,ctype: string; + sdetect : Tdetect_cdm; +begin + if debugBranche then AfficheDebug('Création branche depuis aiguillage '+intToSTR(AdrAig),clyellow); + raz_detect(sdetect); + AdrAigRencontre:=0; + i:=0; Naig:=0; + repeat + if nivdebug=3 then + begin + numsegment:=segment[indexSeg].numero; + NumPort:=segment[indexSeg].port[IndexPort].numero; + AfficheDebug(intToSTR(i)+' Trouve suivant au= '+intToSTR(numSegment)+' '+intToSTR(NumPort),clOrange); + end; + trouve:=trouve_Seg_suivant(indexSeg,indexport,IndexSegSuivant,IndexportSuivant); // indexSeg=48 + if not(trouve) then + begin + s:='Pas de segment suivant à '+intToSTR(numSegment)+' '+intToSTR(NumPort); + affiche(s,clred); + afficheDebug(s,clred); + end; + + if trouve then + begin + raz_detect(sdetect); + numsegment:=segment[indexSegSuivant].numero; + NumPort:=segment[indexSegSuivant].port[IndexPortSuivant].numero; + //if debugBranche then + if NivDebug=3 then AfficheDebug(' Suivant= '+intToSTR(numSegment)+' '+intToSTR(NumPort),clOrange); + ctype:=segment[indexSegSuivant].typ; + + // est-ce un aiguillage + if segment_aig(ctype) then + begin + AdrAigRencontre:=segment[indexSegSuivant].adresse; + if NivDebug=3 then Affichedebug('aig '+intTostr(adrAigRencontre),clyellow); + sBranche:=sBranche+',A'+intToSTR(AdrAigRencontre); + //if debugBranche then AfficheDebug('Aiguillage '+intToSTR(segment[indexSegSuivant].adresse),clorange); + inc(nAig); // à la première itération on a un aiguillage + raz_detect(sdetect); + end; + + // est-ce un croisement + if ctype='crossing' then + begin + sBranche:=sBranche+',A'+intToSTR(segment[indexSegSuivant].adresse); + if NivDebug=3 then Affichedebug('croisement',clyellow); + //if debugBranche then AfficheDebug('Croisement '+intToSTR(segment[indexSegSuivant].adresse),clorange); + raz_detect(sdetect); + end; + + if ctype='bumper_stop' then + begin + sBranche:=sBranche+',0'; + if NivDebug=3 then Affichedebug('buttoir',clyellow); + //if debugBranche then AfficheDebug('Buttoir',clorange); + trouve:=false; + raz_detect(sdetect); + end; + + if ctype='turntable' then + begin + sBranche:=sBranche+',0'; + if NivDebug=3 then Affichedebug('table tournante',clyellow); + //if debugBranche then AfficheDebug('Buttoir',clorange); + trouve:=false; + raz_detect(sdetect); + end; + + //else + + begin + // y a til un détecteur + NombrePeriph:=segment[indexSegSuivant].nperiph; + + j:=0;detecteur:=0; + if NombrePeriph<>0 then // on peut rencontrer des détecteurs non appairés: ex ; 514 522 514 522 + begin + nb_det:=0; + repeat + if segment[indexSegSuivant].periph[j].typ='detector' then + begin + detecteur:=segment[indexSegSuivant].periph[j].adresse; + if detecteur<>0 then + begin + if NivDebug=3 then Affichedebug('Détecteur '+inttoStr(detecteur),clyellow); + // incrémenter le compteur du détecteur rencontré + inc(nb_det); + sDetect[nb_det].adresse:=detecteur ; + // coordonnées du port + xp:=segment[indexSegSuivant].Port[IndexPortSuivant].x; + yp:=segment[indexSegSuivant].Port[IndexPortSuivant].y; + // coordonnées du détecteur + xd:=segment[indexSegSuivant].periph[j].x; + yd:=segment[indexSegSuivant].periph[j].y; + // calculer la distance du détecteur au port + sDetect[nb_det].distance:=round( sqrt( sqr(xp-xd)+sqr(yp-yd) )); + end; + end; + inc(j); + until (j>NombrePeriph-1) ; + + // trier les détecteurs du segment dans l'ordre de la distance de la plus + // courte à la plus grande au port + if nb_det<>0 then + begin + trier(Sdetect,nb_det); + + for j:=1 to nb_det do + begin + detecteur:=sDetect[j].adresse; + ss:=dernier_champ(sbranche); + k:=0; + val(ss,k,erreur); + if ss<>'' then if not(ss[1] in['0'..'9']) then k:=0; + // vérifier si le détecteur est déja en fin de branche + if k<>detecteur then + begin + sbranche:=sbranche+','+intToSTR(detecteur); + if NivDebug=3 then Affichedebug('Détecteur pris en compte : '+intToSTR(detecteur),clyellow); + end; + inc(indexElBranche); + end; + end; + end; + + // préparer le suivant , variables : indexSeg et IndexPort + indexSeg:=indexSegSuivant; + + // trouver le port de l'autre côté du segment + port:=trouve_port_suivant(IndexSegSuivant,numport); + trouve_IndexSegPort(Numsegment,port,rien,indexPort); + end; + end; + inc(i); + + until not(trouve) or (nAig=NbreMaxiAigRencontres) or (i>50) or (adrAig=AdrAigRencontre); + + if debugBranche then + begin + if not(trouve) then AfficheDebug('Arrêt sur non trouvé suivant ou buttoir ou table',clYellow); + if (adrAig=AdrAigRencontre) then AfficheDebug('Arret sur bouclage d''aiguillage',clyellow); + if nAig=NbreMaxiAigRencontres then AfficheDebug('Arret sur aiguillage '+intToSTR(segment[indexSeg].adresse),clYellow); + if i>50 then AfficheDebug('Arret sur itérations',clyellow); + end; + + // vérifier si la branche créée est valide --------------------------------- + // 1 vérifier si le dernier élément est un A ou buttoir + i:=0; + repeat + j:=i; + i:=posEx(',',sbranche,j+1); + until i=0; + ss:=copy(sbranche,j+1,length(sbranche)-j); // dernier élément de la branche + ss2:=copy(ss,2,length(sbranche)-1); + val(ss2,i,erreur); + // ok + if (i<>0) and (ss[1]<>'A') then + begin + if debugBranche then + begin + AfficheDebug('La branche '+sbranche,clOrange); + AfficheDebug('est invalide car le dernier élément n''est ni un aiguillage ni un buttoir',clOrange); + end; + exit; // branche invalide, elle n'est pas prise en compte + end; + + // vérifier si un des détecteurs de la branche existe déja dans les branches précédentes + trouve:=false; + if NbreBranches>0 then + begin + s:=sbranche; + repeat + if s[1]<>'A' then + begin + val(s,detecteur,erreur); + if detecteur<>0 then + begin + // balayer les branches + i:=1; + repeat + ss:=branche[i]; + repeat + if ss[1]<>'A' then + begin + val(ss,det2,erreur); + trouve:=det2=detecteur; + //if trouve then Affiche('Trouvé detecteur '+IntToSTR(det2)+' en branche '+intToSTR(i),clred); + end; + j:=pos(',',ss); + if j<>0 then delete(ss,1,j); + until (j=0) or trouve; + inc(i); + until (i=NbreBranches+1) or trouve; + end; + end; + k:=pos(',',s); + if k<>0 then delete(s,1,k); + until (k=0) or trouve; + end; + if trouve then + begin + if debugBranche then + begin + AfficheDebug('La branche '+sBranche,clorange); + AfficheDebug('est inutile car un de ses détecteurs '+intToSTR(detecteur)+' existe dans la branche '+intToSTR(i-1),clOrange); + exit; + end; + end; + + // ok + inc(NbreBranches); + branche[nbreBranches]:=sBranche; + if debugBranche then AfficheDebug('Création branche '+sBranche,clwhite); +end; + +// crée une branche contenant le détecteur detecteur +procedure cree_branche_det(detecteur : integer); +var i,NumSegment,rien,indexSeg,IndexPeriph,indexPort,IndexSegSuivant,portSuivant,IndexportSuivant,adresse : integer; + ctype,s : string; + trouve : boolean; +begin + if debugBranche then + begin + AfficheDebug('------------------',clyellow); + AfficheDebug('Créée branche détecteur '+intToSTR(detecteur),clOrange); + end; + trouve:=trouve_IndexSegPortDetecteur(detecteur,indexSeg,indexPeriph); + numSegment:=Segment[indexSeg].numero; + if nivdebug=3 then AfficheDebug('Le segment porteur du détecteur est le '+intToSTR(numSegment)+' Periph '+intToSTR(Segment[indexSeg].periph[indexperiph].numero),clyellow); + indexport:=0 ; // essayer depuis le port 0 //***************************************ZZZZZZZZZZZZZZZ + + // parcourir les segments jusqu'au prochain aiguillage + i:=0; + repeat + //if trouve then Affiche(intToSTR(numSegment)+' '+intToSTR(indexPeriph),clyellow); + inc(i); + trouve:=trouve_Seg_suivant(indexSeg,indexport,IndexSegSuivant,IndexportSuivant); + if not(trouve) then + begin + s:='Erreur 678 : Pas trouvé d''aiguillage ou de buttoir après le segment / port '+intToSTR(numSegment)+'/'+intToSTR(Segment[indexSeg].port[indexPort].numero); + AfficheDebug(s,clred); + Affiche(s,clred); + sBranche:=''; + exit; + end; + numSegment:=Segment[indexSegSuivant].numero; + portSuivant:=Segment[indexSegSuivant].port[IndexPortSuivant].numero; + if nivdebug=3 then AfficheDebug('Suivant= '+intToSTR(numSegment)+' indexport '+intToSTR(IndexportSuivant),clYellow); + ctype:=segment[IndexSegSuivant].typ; + if ctype='bumper_stop' then + begin + // repartir en sens inverse + if indexPortSuivant=0 then indexPortSuivant:=1 else indexPortSuivant:=0; + portSuivant:=Segment[indexSegSuivant].port[IndexPortSuivant].numero; + end; + // si on rencontre une table, çà revient dans l'autre sens + + trouve:=segment_aig(ctype); // est-ce un aiguillage ??? + + // prépare suivant + if not(trouve) then + begin + IndexSeg:=IndexSegSuivant; + port:=trouve_port_suivant(indexSegSuivant,portSuivant); + trouve_IndexSegPort(Numsegment,port,rien,indexPort); + end; + until (i=50) or trouve; + + if not(trouve) then + begin + s:='68 : Pas trouvé d''aiguillage à proximité du détecteur '+intToSTR(detecteur); + AfficheDebug(s,clred); + Affiche(s,clred); + end; + + //partir de IndexSegSuivant, IndexPort + adresse:=segment[IndexSegSuivant].adresse; + sBranche:='A'+intToSTR(Adresse); + //convertir le port en index + IndexPort:=trouve_IndexPort_Segment(IndexSegSuivant,portSuivant); + + Cree_branche_aig(IndexSegSuivant,IndexPort,adresse,1); // 1 aiguillage rencontré maxi + + +end; + +// procédure principale de création des branches +procedure creee_branches; +var i,j,k,adresse,detecteur,indexSeg,det2,erreur : integer; + trouve : boolean; + c : char; + s : string; +begin + // l'origine d'une branche est la pointe d'un aiguillage connecté à un détecteur ---------- + NbreBranches:=0; + + Affiche('Création des branches',clWhite); + if debugBranche then AfficheDebug('Etape 3.1 création des branches de pointe d''aiguillage à pointe d''aiguillage',clwhite); + i:=1; + repeat + c:=aiguillage[i].APointeB; + trouve:=(c<>'S') and (c<>'D') and (c<>'P') and (aiguillage[i].modele<>crois) and (aiguillage[i].modele<>tjd); + // si la pointe de l'aiguillage est <> de S D P, c'est qu'il est connecté à un détecteur + if trouve then + begin + adresse:=aiguillage[i].Adresse; + detecteur:=aiguillage[i].APointe; + if debugBranche then + begin + AfficheDebug('-------------------------',clyellow); + AfficheDebug('Début de branche n°'+intToSTR(NbreBranches+1)+' : aiguillage '+intToSTR(adresse)+' Pointe='+intToSTR(detecteur),clyellow); + end; + + trouve:=trouve_IdSegment_aig(adresse,indexSeg); + if not(trouve) then affiche('Erreur 417 : Aig '+intToSTR(adresse)+' non trouvé ',clred); + //Affiche(IntToSTR(segment[indexSeg].numero),clYellow); + + if trouve then + begin + port:=segment[indexSeg].port[0].numero; // on commence par le port 0 (pointe) de l'aiguillage + sBranche:='A'+intToSTR(adresse); + cree_branche_aig(indexSeg,0,adresse,100); // branche dans sBranche + if nivdebug=3 then AfficheDebug(sbranche,clwhite); + end; + end; + inc(i); // aiguillage suivant + trouve:=false; + until trouve or (i>MaxAiguillage); + + // puis créer les branches depuis les positions déviées --------------------- + if debugBranche then AfficheDebug('Etape 3.2 création des branches de dévié d''aiguillage',clwhite); + i:=1; + repeat + c:=aiguillage[i].AdevieB; + trouve:=(c<>'S') and (c<>'D') and (c<>'P') and (aiguillage[i].modele<>crois) and (aiguillage[i].modele<>tjd); + // si la déviée de l'aiguillage est <> de S D P, c'est qu'il est connecté à un détecteur + if trouve then + begin + adresse:=aiguillage[i].Adresse; + detecteur:=aiguillage[i].Adevie; + if debugBranche then AfficheDebug('Début de branche n°'+intToSTR(NbreBranches+1)+' : aiguillage '+intToSTR(adresse)+' dévié='+intToSTR(detecteur),clyellow); + + trouve:=trouve_IdSegment_aig(adresse,indexSeg); + if not(trouve) then affiche('Erreur 418 : Aig '+intToSTR(adresse)+' non trouvé ',clred); + //Affiche(IntToSTR(segment[indexSeg].numero),clYellow); + + if trouve then + begin + port:=segment[indexSeg].port[2].numero; // on commence par le port 2 cdm (pointe) de l'aiguillage + sBranche:='A'+intToSTR(adresse); + cree_branche_aig(indexSeg,2,adresse,100); // port 2 + if nivdebug=3 then AfficheDebug(sbranche,clwhite); + end; + end; + inc(i); // aiguillage suivant + trouve:=false; + until trouve or (i>MaxAiguillage); + + if debugBranche then AfficheDebug('Etape 3.3 Liste de détecteurs absents des branches pour constituer les branches manquantes',clwhite); + // regarder la liste des détecteurs de CDM qui sont absents des branches-------------------- + for i:=1 to Ndet_cdm do + begin + detecteur:=det_CDM[i]; + trouve:=false; + for j:=1 to NbreBranches do + begin + s:=branche[j]; + repeat + if s[1]<>'A' then + begin + val(s,det2,erreur); + trouve:=trouve or (det2=detecteur); + end; + k:=pos(',',s); + if k<>0 then delete(s,1,k); + until (k=0) or trouve; + end; + if not(trouve) then + begin + if debugBranche then AfficheDebug('le détecteur '+intToSTR(detecteur)+' est absent des branches ',clOrange); + cree_branche_det(detecteur); + //if debugBranche then AfficheDebug(sbranche,clWhite); + end; + end; + + // recopier le tampon des branches dans le richedit de l'onglet branches de la config + with formconfig do + begin + RichBranche.clear; + clicListe:=true; + for i:=1 to NbreBranches do + begin + s:=Branche[i]; + RichBranche.Lines.Add(s); + RE_ColorLine(RichBranche,RichBranche.lines.count-1,ClAqua); + end; + With RichBranche do + begin + SelStart:=0; + Perform(EM_SCROLLCARET,0,0); + end; + end; + clicListe:=false; + + +end; + + +procedure Compilation; +var s : string; + i,nombre,position : integer; + +begin + ndet_cdm:=0; + debugAnalyse:=true; + debugBranche:=true; Lignes:=Formprinc.FenRich.Lines; nligne:=0; nSeg:=0; + DernAdrAig:=0; xminiCDM:=0;yMiniCDM:=0;xmaxiCDM:=0;yMaxiCDM:=0; nombre:=Formprinc.FenRich.Lines.Count; NomModule:=Lignes[0]; formAnalyseCDM.Caption:='Squelette du réseau '+NomModule; Affiche('Compilation en cours',clWhite); - + if DebugBranche then AfficheDebug('Compilation des segments, ports, inter et périphériques de CDM rail',ClWhite); repeat s:=supprime_espaces(lignes[nligne]); position:=pos('segment #',s) ; if position=1 then @@ -1306,18 +2227,21 @@ begin //Affiche('fin de la compilation',cllime); Affichage; + Affiche('nombre de détecteurs: '+intToSTR(NDet_cdm),clyellow); formAnalyseCDM.Show; formprinc.ButtonAffAnalyseCDM.Visible:=true; - Affiche('Compilation terminée',clWhite); - // crée - cree; + Affiche('Compilation terminée. Nombre de segments='+intToSTR(nSeg),clWhite); + + remplit_Aig_cdm; + Affiche('nombre de d''aiguillages: '+intToSTR(Naig_cdm),clyellow); if MaxAiguillage<>0 then begin if MessageDlg('Une configuration de réseau existe dans signaux complexes.'+#10+#13+ - 'Si vous importez le réseau CDM, la configuration des aiguillages de signaux complexes sera écrasée.'+#10+#13+ - 'Voulez vous continuer l''importation? (aiguillages)',mtConfirmation,[mbyes,mbNo],0)=mrNo then + 'Si vous importez le réseau CDM, la configuration des aiguillages et des branches '+#10+#13+ + 'de Signaux_complexes sera écrasée.'+#10+#13+ + 'Voulez vous continuer l''importation? (aiguillages & branches)',mtConfirmation,[mbyes,mbNo],0)=mrNo then begin Affiche('Importation annulée',clOrange); exit; @@ -1326,11 +2250,12 @@ begin MaxAiguillage:=0; - Affiche('Importation en cours',clWhite); + Affiche('Importation des aiguillages',clWhite); // recopier les aiguillages for i:=1 to NAig_CDM do begin Aiguillage[i].adresse:=Aig_CDM[i].adresse; + Aiguillage[i].adrtriple:=Aig_CDM[i].adrtriple; Aiguillage[i].modele:=Aig_Cdm[i].modele; Aiguillage[i].temps:=Aig_cdm[i].temps; Aiguillage[i].ADroit:=Aig_Cdm[i].ADroit; @@ -1350,6 +2275,16 @@ begin aiguillage[i].vitesse:=0; end; MaxAiguillage:=NAig_CDM; + trier_aig; + + + // créer les branches pour version 6.1 + creee_branches; + + Affiche('Validation des branches',ClLime); + valide_branches; + for i:=1 to NbreBranches do + compile_branche(Branche[i],i); Affiche('Importation terminée',clWhite); Affiche('Vérification de la cohérence :',clWhite); @@ -1384,8 +2319,7 @@ begin end; procedure TFormAnalyseCDM.ButtonAffPortClick(Sender: TObject); -var i,j,port,numport,erreur : integer; - trouve : boolean; +var i,j,numport,erreur : integer; begin val(editPort.text,numport,erreur); trouve_IndexPort(numport,i,j); @@ -1395,11 +2329,89 @@ begin end; procedure TFormAnalyseCDM.FormCreate(Sender: TObject); + begin checkPorts.Checked:=true; + radioCroisBase.Checked:=true; + radioCroisSuite.checked:=false; + BaseCroisement:=100; + EditBaseCrois.Text:=IntToSTR(BaseCroisement); + + + +end; + +procedure Analyse_Seg; +begin + formAnalyseCDM.Show; + //compilation; end; +procedure TFormAnalyseCDM.ButtonImporterClick(Sender: TObject); +var startAngle,stopAngle : double; + centreX,CentreY,rayon,x1,y1,x2,y2 : integer; + r : Trect; +begin + //FormAnalyseCDM.WindowState:=wsMinimized; + Compilation; + exit; + with FormAnalyseCDM.ImageCDM.Canvas do + begin + //effacer tout + Pen.width:=1; + Brush.Style:=bsSolid; + Brush.Color:=clblack; + pen.color:=clyellow; + r:=rect(0,0,FormAnalyseCDM.ImageCDM.width,FormAnalyseCDM.ImageCDM.height); + FillRect(r); + x1:=xminiCDM;y1:=yminiCDM; + coords(x1,y1); + x2:=xmaxiCDM;y2:=ymaxiCDM; + coords(x2,y2); + end; + + + D_arc(FormAnalyseCDM.ImageCDM.Canvas,300,200,100,90,30); + exit; + //46 + ImageCDM.canvas.pen.color:=clLime; + StartAngle:=90; //+AncienStart; // relatif par rapport au dernier!!! + StopAngle:=-30; + centreX:=21850;centreY:=18310; + rayon:=6500; + angle_cdm(centreX,CentreY,startangle,stopangle,rayon); + //55 + ImageCDM.canvas.pen.color:=clred; + StartAngle:=60; //+AncienStart; // relatif par rapport au dernier!!! + StopAngle:=-30; + centreX:=21850;centreY:=18310; + rayon:=6500; + angle_cdm(centreX,CentreY,startangle,stopangle,rayon); + +end; + +procedure TFormAnalyseCDM.CheckDebugAnalyseClick(Sender: TObject); +begin + debugAnalyse:=checkDebugAnalyse.checked; +end; + +procedure TFormAnalyseCDM.CheckDebugBranchesClick(Sender: TObject); +begin + debugBranche:=checkDebugBranches.checked; +end; + +procedure TFormAnalyseCDM.EditBaseCroisChange(Sender: TObject); +var i,erreur : integer; +begin + val(editBaseCrois.text,i,erreur); + if erreur=0 then BaseCroisement:=i; +end; + +procedure TFormAnalyseCDM.CheckPortsClick(Sender: TObject); +begin + Affichage; +end; end. diff --git a/UnitConfig.dfm b/UnitConfig.dfm index 9d20d29..465d13c 100644 --- a/UnitConfig.dfm +++ b/UnitConfig.dfm @@ -1571,7 +1571,7 @@ object FormConfig: TFormConfig Top = 8 Width = 633 Height = 505 - ActivePage = TabSheetSig + ActivePage = TabSheetAig Font.Charset = DEFAULT_CHARSET Font.Color = clBlack Font.Height = -11 @@ -2925,6 +2925,7 @@ object FormConfig: TFormConfig Lines.Strings = ( 'RichBranche') ParentFont = False + PopupMenu = PopupMenuConfig ScrollBars = ssBoth TabOrder = 1 WordWrap = False @@ -3128,7 +3129,7 @@ object FormConfig: TFormConfig Width = 129 Height = 21 Style = csDropDownList - ItemHeight = 13 + ItemHeight = 0 TabOrder = 1 OnChange = ComboBoxDecChange end @@ -4836,4 +4837,16 @@ object FormConfig: TFormConfig Left = 668 Top = 468 end + object PopupMenuConfig: TPopupMenu + Left = 728 + Top = 88 + object Copier1: TMenuItem + Caption = 'Copier' + OnClick = Copier1Click + end + object Coller1: TMenuItem + Caption = 'Coller' + OnClick = Coller1Click + end + end end diff --git a/UnitConfig.pas b/UnitConfig.pas index f4a30f6..85902ee 100644 --- a/UnitConfig.pas +++ b/UnitConfig.pas @@ -5,7 +5,8 @@ interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls , jpeg, ComCtrls ,StrUtils, Unitprinc, - MMSystem, Buttons , UnitPareFeu, verif_version; + MMSystem, Buttons , UnitPareFeu, verif_version, + Menus; type TFormConfig = class(TForm) @@ -333,6 +334,9 @@ type EditZdet1V5O: TEdit; EditZdet2V5O: TEdit; Label60: TLabel; + PopupMenuConfig: TPopupMenu; + Copier1: TMenuItem; + Coller1: TMenuItem; procedure ButtonAppliquerEtFermerClick(Sender: TObject); procedure FormActivate(Sender: TObject); procedure FormCreate(Sender: TObject); @@ -489,6 +493,8 @@ type procedure EditZdet2V5OChange(Sender: TObject); procedure EditLAYChange(Sender: TObject); procedure EditLAYExit(Sender: TObject); + procedure Copier1Click(Sender: TObject); + procedure Coller1Click(Sender: TObject); private { Déclarations privées } public @@ -573,6 +579,8 @@ Procedure aff_champs_sig_feux(index : integer); function verif_coherence : boolean; function compile_branche(s : string;i : integer) : boolean; function encode_sig_feux(i : integer): string; +procedure valide_branches; +procedure trier_aig; implementation @@ -2786,6 +2794,7 @@ begin begin trouve_section_aig:=true; compile_aiguillages; + trier_aig; end; // section branche @@ -4679,6 +4688,7 @@ begin if index=0 then exit; aiguillage[index].Adroit:=adr; aiguillage[index].AdroitB:=B; + LabelInfo.caption:='Modification de la TJD homologe ('+IntToSTR(adr2)+')'; end; // TJD2 if aiguillage[index].EtatTJD=2 then @@ -4689,7 +4699,6 @@ begin s:=encode_aig(index); formconfig.RichAig.Lines[index-1]:=s; RE_ColorLine(Formconfig.RichAig,index-1,ClWhite); - LabelInfo.caption:='Modification de la TJD homologe ('+IntToSTR(adr2)+')'; end; if modele=crois then @@ -6318,6 +6327,26 @@ begin config_modifie:=true; end; + +// trie les aiguillages +procedure trier_aig; +var i,j : integer; + temp : TAiguillage; +begin + for i:=1 to MaxAiguillage do + begin + for j:=i+1 to MaxAiguillage do + begin + if aiguillage[i].Adresse>aiguillage[j].adresse then + begin + temp:=aiguillage[i]; + aiguillage[i]:=aiguillage[j]; + aiguillage[j]:=temp; + end; + end; + end; +end; + procedure supprime_act; var i,debut,longueur,fin,ltot,lignedeb,lignefin,l : integer; s: string; @@ -6811,7 +6840,7 @@ begin end; end; adr:=aiguillage[Indexaig].Adroit; - if (aiguillage[Indexaig].AdroitB='Z') then + if (aiguillage[Indexaig].AdroitB='Z') or (aiguillage[Indexaig].AdroitB=#0) then begin trouve_detecteur(adr); if IndexBranche_trouve=0 then @@ -6821,7 +6850,7 @@ begin end; end; adr:=aiguillage[Indexaig].Adevie; - if (aiguillage[Indexaig].AdevieB='Z') then + if (aiguillage[Indexaig].AdevieB='Z') or (aiguillage[Indexaig].AdevieB=#0) then begin trouve_detecteur(adr); if IndexBranche_trouve=0 then @@ -6831,7 +6860,7 @@ begin end; end; adr:=aiguillage[Indexaig].Apointe; - if ((aiguillage[Indexaig].ApointeB='Z') and (aiguillage[Indexaig].modele=aig)) then + if ( ((aiguillage[Indexaig].ApointeB='Z') or (aiguillage[Indexaig].ApointeB=#0)) and (aiguillage[Indexaig].modele=aig) ) then begin trouve_detecteur(adr); if IndexBranche_trouve=0 then @@ -6842,7 +6871,7 @@ begin end; if (aiguillage[Indexaig].modele=triple) then // aiguillage triple begin - if (aiguillage[Indexaig].Adevie2B='Z') then + if (aiguillage[Indexaig].Adevie2B='Z') or (aiguillage[Indexaig].Adevie2B=#0) then begin adr:=aiguillage[Indexaig].Adevie2; trouve_detecteur(adr); @@ -7144,9 +7173,9 @@ begin end; // on ne vérifie pas les tjd tjs crois - if (model<>tjd) and (model<>tjd) and (model<>crois) then + if (model<>tjd) and (model<>tjd) and (model<>crois) then begin - + adr2:=aiguillage[indexaig].ADroit; // adresse de ce qui est connecté sur la position droite c:=aiguillage[indexaig].AdroitB; if (c='D') or (c='S') or (c='P') then @@ -7154,12 +7183,6 @@ begin if adr2=adr then affiche('Erreur 10.0 : la position droite de l''aiguillage '+intToSTR(adr)+' pointe sur elle même',clred); index2:=Index_aig(adr2); // adresse de l'aiguillage connecté model2:=aiguillage[index2].modele; // modèle de l'aiguillage connecté - if index2=0 then - begin - ok:=false; - Affiche('Erreur 10.20: aiguillage '+intToSTR(adr)+': déclaration d''un aiguillage '+IntToSTR(adr2)+' inexistant',clred); - end - else begin // tjs ou tjs à 2 états ou croisement if ( ((model2=tjs) or (model2=tjd)) and (aiguillage[index2].EtatTJD=2) ) or (model2=crois) then @@ -7167,11 +7190,11 @@ begin if (adr<>aiguillage[index2].Adevie) and (adr<>aiguillage[index2].ADroit) and (adr<>aiguillage[index2].DDevie) and (adr<>aiguillage[index2].Ddroit) then begin - Affiche('Erreur 10.21: Discordance de déclaration aiguillages '+intToSTR(adr)+': '+intToSTR(adr2),clred); + Affiche('Erreur 10.21: Discordance de déclaration aiguillages '+intToSTR(adr)+': '+intToSTR(adr2),clred); ok:=false; - end; + end; end; - + // tjs ou tjs à 4 états if (((model2=tjs) or (model2=tjd)) and (aiguillage[index2].EtatTJD=4)) then begin @@ -7180,7 +7203,7 @@ begin if (adr<>aiguillage[index2].Adevie) and (adr<>aiguillage[index2].ADroit) and (adr<>aiguillage[index3].ADevie) and (adr<>aiguillage[index3].Adroit) then begin - Affiche('Erreur 10.22: Discordance de déclaration aiguillages '+intToSTR(adr)+': '+intToSTR(adr2),clred); + Affiche('Erreur 10.22: Discordance de déclaration aiguillages '+intToSTR(adr)+': '+intToSTR(adr2),clred); ok:=false; end; end; @@ -7205,7 +7228,7 @@ begin end; end; end; - + adr2:=aiguillage[indexaig].Adevie; // adresse de ce qui est connecté sur la position déviée c:=aiguillage[indexaig].AdevieB; if (c='D') or (c='S') or (c='P') then @@ -7272,12 +7295,6 @@ begin if adr2=adr then affiche('Erreur 10.2 : la pointe de l''aiguillage '+intToSTR(adr)+' pointe sur elle même',clred); index2:=Index_aig(adr2); // adresse de l'aiguillage connecté model2:=aiguillage[index2].modele; // modèle de l'aiguillage connecté - if index2=0 then - begin - ok:=false; - Affiche('Erreur 10.40: aiguillage '+intToSTR(adr)+': déclaration d''un aiguillage '+IntToSTR(adr2)+' inexistant',clred); - end - else begin // tjs ou tjs à 2 états ou croisement if (((model2=tjs) or (model2=tjd)) and (aiguillage[index2].EtatTJD=2)) or (model2=crois) then @@ -8104,7 +8121,7 @@ begin end; -procedure TFormConfig.ButtonValLigneClick(Sender: TObject); +procedure valide_branches; var s: string; ligne,esp : integer; ok : boolean; @@ -8112,7 +8129,7 @@ begin ligne:=1; ok:=true; repeat - s:=AnsiUpperCase(RichBranche.Lines[ligne-1]); + s:=AnsiUpperCase(formConfig.RichBranche.Lines[ligne-1]); if s<>'' then begin // supprime les espaces éventuels @@ -8122,24 +8139,24 @@ begin until esp=0; if s<>'' then begin - RichBranche.Lines[ligne-1]:=s; + formConfig.RichBranche.Lines[ligne-1]:=s; branche[ligne]:=s; // stocker la ligne dans la branche pour la compiler if compile_branche(s,ligne) then begin - RE_ColorLine(RichBranche,Ligne-1,ClLime); + RE_ColorLine(FormConfig.RichBranche,Ligne-1,ClLime); end else begin - RE_ColorLine(RichBranche,Ligne-1,ClRed); + RE_ColorLine(FormConfig.RichBranche,Ligne-1,ClRed); ok:=false; end; inc(ligne); end - else RichBranche.Lines.Delete(ligne-1); + else FormConfig.RichBranche.Lines.Delete(ligne-1); end - else RichBranche.Lines.Delete(ligne-1); + else FormConfig.RichBranche.Lines.Delete(ligne-1); - until (ligne>RichBranche.Lines.count) or (ligne>=MaxBranches); + until (ligne>FormConfig.RichBranche.Lines.count) or (ligne>=MaxBranches); NbreBranches:=ligne-1; if ligne>=MaxBranches then Affiche('Nombre maximal de branches atteint',clRed); @@ -8147,16 +8164,21 @@ begin if ligne<>0 then begin ok:=false; - RE_ColorLine(RichBranche,Ligne-1,ClRed); - end; + RE_ColorLine(FormConfig.RichBranche,Ligne-1,ClRed); + end; if ok then begin - labelResult.Caption:='Syntaxe correcte'; + FormConfig.labelResult.Caption:='Syntaxe correcte'; config_modifie:=true; modif_branches:=false; end - else labelResult.Caption:='Erreur de syntaxe'; + else FormConfig.labelResult.Caption:='Erreur de syntaxe'; +end; + +procedure TFormConfig.ButtonValLigneClick(Sender: TObject); +begin + valide_branches; end; function virgule_suiv(sl : string;o : integer) : integer; @@ -10147,6 +10169,21 @@ procedure TFormConfig.EditLAYExit(Sender: TObject); LabelInfo.caption:=''; end; +procedure TFormConfig.Copier1Click(Sender: TObject); + begin + RichBranche.CopyToClipboard; + RichBranche.SetFocus; +end; + +procedure TFormConfig.Coller1Click(Sender: TObject); + begin + With RichBranche do + begin + PasteFromClipboard; + SetFocus; + end; +end; + end. diff --git a/UnitDebug.dfm b/UnitDebug.dfm index 128dec1..48b34a1 100644 --- a/UnitDebug.dfm +++ b/UnitDebug.dfm @@ -482,22 +482,6 @@ object FormDebug: TFormDebug TabOrder = 10 OnClick = CheckDetSIgClick end - object CheckImporteCDM: TCheckBox - Left = 256 - Top = 96 - Width = 129 - Height = 17 - Alignment = taLeftJustify - Caption = 'Importation CDM Rail' - Font.Charset = DEFAULT_CHARSET - Font.Color = clBlack - Font.Height = -11 - Font.Name = 'MS Sans Serif' - Font.Style = [] - ParentFont = False - TabOrder = 11 - OnClick = CheckImporteCDMClick - end end object RichDebug: TRichEdit Left = 8 diff --git a/UnitDebug.pas b/UnitDebug.pas index 3fb39eb..d206ce7 100644 --- a/UnitDebug.pas +++ b/UnitDebug.pas @@ -63,7 +63,6 @@ type Button0: TButton; MemoEvtDet: TRichEdit; CheckDetSIg: TCheckBox; - CheckImporteCDM: TCheckBox; procedure FormCreate(Sender: TObject); procedure ButtonEcrLogClick(Sender: TObject); procedure EditNivDebugKeyPress(Sender: TObject; var Key: Char); @@ -102,7 +101,6 @@ type procedure FormActivate(Sender: TObject); procedure MemoEvtDetChange(Sender: TObject); procedure CheckDetSIgClick(Sender: TObject); - procedure CheckImporteCDMClick(Sender: TObject); private { Déclarations privées } public @@ -112,7 +110,7 @@ type var FormDebug: TFormDebug; NivDebug,signalDebug,compt_erreur,positionErreur,LigneErreur : integer; - AffSignal,AffAffect,initform,AffFD,debug_dec_sig,debugTCO,DebugAffiche,AFfDetSIg,debugAnalyse : boolean; + AffSignal,AffAffect,initform,AffFD,debug_dec_sig,debugTCO,DebugAffiche,AFfDetSIg : boolean; N_event_det : integer; // index du dernier évènement (de 1 à 20) N_Event_tick : integer ; // dernier index @@ -627,9 +625,8 @@ begin AFfDetSIg:=checkDetSig.checked; end; -procedure TFormDebug.CheckImporteCDMClick(Sender: TObject); -begin - debugAnalyse:=checkImporteCDM.checked; -end; + + + end. diff --git a/UnitPrinc.dfm b/UnitPrinc.dfm index fa7d616..bf62417 100644 --- a/UnitPrinc.dfm +++ b/UnitPrinc.dfm @@ -1,6 +1,6 @@ object FormPrinc: TFormPrinc - Left = 68 - Top = 194 + Left = 86 + Top = 188 Width = 1227 Height = 671 Caption = 'Signaux complexes' @@ -1387,15 +1387,6 @@ object FormPrinc: TFormPrinc WordWrap = True OnClick = ButtonAffAnalyseCDMClick end - object Button2: TButton - Left = 48 - Top = 96 - Width = 75 - Height = 25 - Caption = 'Button2' - TabOrder = 7 - OnClick = Button2Click - end end object StaticText: TStaticText Left = 16 diff --git a/UnitPrinc.pas b/UnitPrinc.pas index 408412a..0a2ffd9 100644 --- a/UnitPrinc.pas +++ b/UnitPrinc.pas @@ -168,7 +168,6 @@ type Analyser1: TMenuItem; Coller1: TMenuItem; ButtonAffAnalyseCDM: TButton; - Button2: TButton; procedure FormCreate(Sender: TObject); procedure MSCommUSBLenzComm(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); @@ -251,8 +250,7 @@ type procedure Analyser1Click(Sender: TObject); procedure Coller1Click(Sender: TObject); procedure ButtonAffAnalyseCDMClick(Sender: TObject); - procedure Button2Click(Sender: TObject); - private + private { Déclarations privées } procedure DoHint(Sender : Tobject); public @@ -310,7 +308,7 @@ Taccessoire = (aigP,feu); // aiguillage ou feu TEquipement = (rien,aig,tjd,tjs,triple,det,buttoir,voie,crois,act); // voie uniquement pour le tco TBranche = record BType : Tequipement ; // ne prend que les valeurs suivantes: dét aig Buttoir - Adresse : integer ; // adresse du détecteur ou de l'aiguillage + Adresse : integer ; // adresse du détecteur ou de l'aiguillage end; Taiguillage = record @@ -13905,6 +13903,9 @@ begin Affiche('Cela ouvre une fenêtre DEBUG dans cdm',clLime); Affiche('Dans cette fenêtre, faire Clic droit puis "sélectionner tout" et "copier"',clLime); Affiche('Dans Signaux complexes, clic droit et "coller ; puis menu divers / Analyse des modules ',clLime); + Affiche('Dans la fenêtre graphique d''importation cliquer sur importer',clLime); + Affiche('Attention : nécessite la version >=23.05 de CDM',clLime); + if lance_cdm(false) then begin @@ -13960,27 +13961,11 @@ end; procedure TFormPrinc.ButtonAffAnalyseCDMClick(Sender: TObject); begin + FormAnalyseCDM.WindowState:=wsMaximized; formAnalyseCDM.Show; end; -procedure TFormPrinc.Button2Click(Sender: TObject); -var i : integer; -begin - i:=index_aig(26); - Affiche(intToSTR(aiguillage[i].ADroit)+aiguillage[i].AdroitB,clred); - Affiche(intToSTR(aiguillage[i].ADevie)+aiguillage[i].AdevieB,clred); - Affiche(intToSTR(aiguillage[i].DDroit)+aiguillage[i].DDroitB,clred); - Affiche(intToSTR(aiguillage[i].Ddevie)+aiguillage[i].DdevieB,clred); - - i:=index_aig(28); - Affiche(intToSTR(aiguillage[i].ADroit)+aiguillage[i].AdroitB,clorange); - Affiche(intToSTR(aiguillage[i].ADevie)+aiguillage[i].AdevieB,clorange); - Affiche(intToSTR(aiguillage[i].DDroit)+aiguillage[i].DDroitB,clorange); - Affiche(intToSTR(aiguillage[i].Ddevie)+aiguillage[i].DDevieB,clorange); - - - -end; + end. diff --git a/Unit_Pilote_aig.dcu b/Unit_Pilote_aig.dcu deleted file mode 100644 index 7b751b7..0000000 Binary files a/Unit_Pilote_aig.dcu and /dev/null differ diff --git a/versions.txt b/versions.txt index b290cf7..3f2172c 100644 --- a/versions.txt +++ b/versions.txt @@ -163,5 +163,5 @@ version 5.74 : Correction bug cr Nouvel installeur-> Signaux complexes s'installe dans c:\programmes\signaux_complexes. avec un raccourci sur le bureau. version 6.0 : Gestion du décodeur de signaux Arcomora. - Importation des aiguillages depuis CDM Rail. + Importation des aiguillages et des branches depuis CDM Rail. Nécessite la version >=23.04 de CDM rail.