Einzelnen Beitrag anzeigen

Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#21

AW: dynamische Verwaltung von Objekten - Fahrstuhlsteuerung

  Alt 14. Jun 2013, 12:05
Der Fehler in der Umsetzung ist der, dass bei der Anweisung "Schließe die Tür" der komplette Vorgang abgearbeitet wird.
In der Praxis wäre es so, dass beim Drücken des Schließen-Knopfes alle Knöpfe ihre Funktion verlieren (blockiert sind), bis die Tür geschlossen ist.

Im Anhang habe ich mal ein kleines Projekt für eine Fahrstuhltür, die man auch im laufenden Betrieb wieder öffnen kann.

Basisklasse
Delphi-Quellcode:
  EElevator = class( Exception );

  TElevatorDoorState = ( edsClosed, edsClosing, edsOpening, edsOpen );

  TElevatorDoor = class( TProgressEntity )
  protected
    function GetPosition : Integer; virtual; abstract;
    function GetState : TElevatorDoorState; virtual; abstract;
  public
    // Nur zur Visualisierung (0-100)
    property Position : Integer read GetPosition;
    // Status
    property State : TElevatorDoorState read GetState;
    // Befehle
    procedure Open; virtual; abstract;
    procedure Close; virtual; abstract;
  end;
und konkret
Delphi-Quellcode:
  TDumbElevatorDoor = class( TElevatorDoor )
  private
    // Öffnen-/Schließ-Geschwindigkeit in m/s
    FDirection : Extended;
    // Position der Tür in m (0m - 1m)
    FPosition : Extended;
  protected
    function GetState : TElevatorDoorState; override;
    function GetPosition : Integer; override;
    procedure Progress( const IntervalMS : Cardinal ); override;
  public
    procedure Open; override;
    procedure Close; override;
  end;

implementation

uses
  System.Math;

const
  cEpsilon = 0.001;

  { TDumbElevatorDoor }

procedure TDumbElevatorDoor.Close;
begin
  FDirection := - 0.3; // 0.3m/s Schließgeschwindigkeit
end;

function TDumbElevatorDoor.GetPosition : Integer;
begin
  Result := 100 - Round( FPosition * 100 );
end;

function TDumbElevatorDoor.GetState : TElevatorDoorState;
begin
  if FDirection > 0
  then
    Result := edsOpening
  else if FDirection < 0
  then
    Result := edsClosing
  else if SameValue( FPosition, 0, cEpsilon )
  then
    Result := edsClosed
  else if SameValue( FPosition, 1, cEpsilon )
  then
    Result := edsOpen
  else
    raise EElevator.Create( 'Fahrstuhltür defekt' );
end;

procedure TDumbElevatorDoor.Open;
begin
  FDirection := 0.5; // 0.5m/s Öffnen-Geschwindigkeit
end;

procedure TDumbElevatorDoor.Progress( const IntervalMS : Cardinal );
var
  LNewPosition : Extended;
begin

  LNewPosition := FPosition + FDirection / 1000 * IntervalMS;

  if LNewPosition >= 1
  then
    begin
      FPosition := 1;
      FDirection := 0;
    end
  else if LNewPosition <= 0
  then
    begin
      FPosition := 0;
      FDirection := 0;
    end
  else
    FPosition := LNewPosition;

end;
Angehängte Dateien
Dateityp: zip TaktGeber.zip (837,2 KB, 14x aufgerufen)
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat