C# 2005 Hochregal

ftComputing : Programme für die fischertechnik-Interfaces und -konstruktionskästen
  
ftComputing.de
Home
Back
Sitemap
Index
Links
Impressum
Mail
 

Das Hochregallager aus ROBO TX Automation Robots

 

Wird mit den RoboPro-Programmen Hochregal1 - 3 ausgeliefert (RoboPro v3.10, Firmware v1.24). Hier einige Programmvarianten in C# 2005 und FishFaceTX.DLL / umFish50.DLL (Version mit ftMscLib.DLL und Treiber von RoboPro v2.1.4.2 Firmware v1.18 - eine neuere ftMscLib.DLL gibt es noch nicht (10.4.11), dazu siehe auch TX-DLLs).

Hochregal1 -> 1:1 Umsetzung des entsprechenden RoboPro-Programmes

Dazu zunächst das Hauptprogramm. Es entspricht genau dem RoboPro-Programm :

private void Action() {
  Referenzfahrt();
  tx.Pause(1000);
  Bereitstellung();
  GabelVor();
  GabelHeben();
  GabelZurueck();
  Platz1();
  GabelHeben();
  GabelVor();
  GabelSenken();
  GabelZurueck();
  Referenzfahrt();
}

Vorher wird bei Klick auf den ACTION-Button der Form in cmdAction_Click noch eine Verbindung zum TX Controller hergestellt (tx.OpenController(txtCom.Text);). Der Name der Verbindung wird dem Text-Controll txtCom.Text entnommen (hier ggf. an eigene Erfordernisse anpassen).

private void Platz1() {
  tx.StartRobMotor(mArm, Dir.Right, 512, 1720);
  tx.StartRobMotor(mTurm, Dir.Right, 512, 3070);
  tx.WaitForMotors(mArm, mTurm);
  posArm += 1720;
  posTurm += 3070;
}

Hier das Unterprogramm zur Positionierung von Arm und Turm durch Encodermotoren. Verwendet werden die FishFace-Methoden StartRobMotor und WaitForMotors. Mit denen die entsprechenden Motoren für eine entsprechende Impulszahl gestartet werden. Anschließend wird dann auf deren Erreichen gewartet. In posArm und posTurm wird die aktuelle Position des Robots nachgehalten.

private void GabelVor() {
  if (tx.GetInput(iGreiferV)) return;
  tx.SetMotor(mGreifer, Dir.Right);
  tx.WaitForHigh(iGreiferV);
  tx.SetMotor(mGreifer, Dir.Off);
}

Die Gabel wird durch einen XS-Motor betrieben, dessen Fahrweg durch Endtaster begrenzt wird. Hier die Routine um die Gabel vorzufahren : SetMotor - WaitForHigh - SetMotor.

FishFace tx = new FishFace();
int posTurm = 0;
int posArm = 0;
const Mot mTurm = Mot.M1;
const Unv iTurm = Unv.I1;
const Cnt cTurm = Cnt.C1;
const Mot mGreifer = Mot.M2;
const Unv iGreiferH = Unv.I2;
const Unv iGreiferV = Unv.I4;
const Mot mArm = Mot.M3;
const Unv iArm = Unv.I3;
const Cnt cArm = Cnt.C3;

Hier noch die Instantiierung der Klasse FishFace, die Deklaration der Positionsvariablen und die Konstanten mit den Namen der beteiligten Komponenten des TX Controllers

Hochregal 1b : Wie 1, aber unter Einsatz von Device-Klassen der FishFaceTX.DLL

FishControl fc = new FishControl();
RobMotors ArmTurm;
LimitedMotor Gabel;
private void Action() {
  Gabel.MoveLeft();             // --- Referenzfahrt
  ArmTurm.MoveHome();
  ArmTurm.MoveTo(0, 40);        // --- Bereitstellung
  Gabel.MoveRight();            // --- Gabel vor
  ArmTurm.MoveDelta(0, 150);    // --- Gabel heben
  Gabel.MoveLeft();             // --- Gabel zurück
  ArmTurm.MoveTo(3100, 1900);   // --- Platz 1
  ArmTurm.MoveDelta(0, 150);    // --- Gabel heben
  Gabel.MoveRight();            // --- Gabel vor
  ArmTurm.MoveDelta(0, -150);   // --- Gabel senken
  Gabel.MoveLeft();             // --- Gabel zurück
  ArmTurm.MoveHome();           // --- Referenzfahrt
}

Das ist denn auch schon das ganze Programm : Deklaration der Objekt für den TX Controller und die Einheit Arm und Turm, sowie die Gabel. Die Unterprogramme von Version 1 lassen sich nahtlos auf Methoden der verwendeten Objekte abbilden, deswegen wurde hier auf Unterprogramme verzichtet.

ArmTurm = new RobMotors(fc, Ctr.Main,
          new RobData(Mot.M1, 6000), new RobData(Mot.M3, 2500));
Gabel = new LimitedMotor(fc, Ctr.Main, Mot.M2, Unv.I2, Unv.I4);

Nachgereicht : Die Instanzierung der genannten Objekte (aus cmdAction_Click) bei der auch die zugehörenden Endtaster und der maximale Fahrweg angegeben werden.

Hochregal 2b : Speichern und Ausgeben von Lagergut

Hier werden die Funktionen von RoboPro Hochregal2/3 nachgebildet. Anstelle der spez. Unterprogramme für jeden Lagerplatz wird hier mit Positionslisten gearbeitet. Die Operation (Ablegen / Holen) und die zugehörende Position werden über die Windows-Form erledigt. Taster I5 wird einheitlich für den Start der Operation verwendet. Die Operationen werden durch entsprechende Texte begleitet.

private void Action() {
  Gabel.MoveLeft(); // --- nach Hause ---
  ArmTurm.MoveHome();
  do {
    if (rdoAblegen.Checked) {
    // --- Ablegen ---
      lblStatus.Text = "Tonne auf Tisch legen, Ready I5";
      Ready.WaitForTrue();
      lblStatus.Text = "Legt die Tonne ab";
      Ablegen(numSpeichern.Value);
    }
    else {
    // --- Holen ---
      lblStatus.Text = "Tisch leer, Ready I5";
      Ready.WaitForTrue();
      lblStatus.Text = "Holt die Tonne";
      Holen(numHolen.Value);
    }
    ArmTurm.MoveHome(); // --- nach Hause ---
  } while (!fc.Finish());
}

Hier wurden Ablegen und Holen in entsprechende Unterprogramme ausgelagert. Action besitzt eine Endlos (do) Schleife, die durch die ESC-Taste abgebrochen werden kann. In der Schleife werden die Radiobuttons für Ablegen und Holen abgefragt und außerdem über Taster an I5 (Ready) ob der Ablagetisch bereit ist, dann wird nur noch Ablegen(); bzw. Holen(); aufgerufen.

private void Holen(decimal HolPos) {
  int holPos = (int)HolPos - 1;
  ArmTurm.MoveTo(PosListe[holPos,0], PosListe[holPos,1]);
  Gabel.MoveRight();
  ArmTurm.MoveDelta(0, 150);
  Gabel.MoveLeft();
  ArmTurm.MoveTo(0, 220);
  Gabel.MoveRight();
  ArmTurm.MoveDelta(0, -150);
  Gabel.MoveLeft();
  }

Hier wird zunächst die Holposition bestimmt (in der Form werden die Plätze mit 1 - 6 angegeben, die PosListe beginnt mit 0). Dann wird die Holposition nach den Werten in der PosListe angefahren und die Gabel - wie schon früher exerziert - gescheucht.

PosListe = new int[,] {{3100, 40},{5000, 40},{3100, 990},{5000, 990},{3100, 1900},{5000, 1900}};

In cmdAction_Click wird dann noch die PosListe besetzt.

Hochregal 3c : Ablegen in erstes freies / Holen aus erstem belegtem Fach

Hier werden die Taster an I5 und I6 genutzt um eine Tonne in das erste freie Fach abzulegen bzw. aus dem ersten belegten Fach zu holen. Dazu wird eine BelegtListe geführt.

private void Action() {
  Gabel.MoveLeft(); // --- nach Hause ---
  ArmTurm.MoveHome();
  do {
    lblStatus.Text = "I5 : Ablegen, I6 Holen";
    if (Store.IsTrue) {
       lblStatus.Text = "Legt die Tonne ab";
       Ablegen();
       ArmTurm.MoveHome(); // --- nach Hause ---
    }
    else if (Fetch.IsTrue) {
      lblStatus.Text = "Holt die Tonne";
       Holen();
       ArmTurm.MoveHome(); // --- nach Hause ---
    }
    fc.Pause(333);
  } while (!fc.Finish());
}

Action ist hier noch kleiner geworden, es wird jetzt zyklisch Store(I5) und Fetch(I6) abgefragt. Holen und Ablegen bestimmen ihre Position jetzt selber.

private void Holen() {
// --- Suchen ersten belegten Platz ---
  int holPos = -1;
  for (int i = 0; i < BelegtListe.Length - 1; i++) {
    if (BelegtListe[i]) {
      holPos = i;
      break;
    }
   }
   if (holPos < 0) {
     lblStatus.Text = "Lager ist leer";
     return;
   }

Eingangs jetzt eine Suchschleife über die BelegtListe nach dem ersten belegten Platz.

  ArmTurm.MoveTo(PosListe[holPos,0], PosListe[holPos,1]);
  Gabel.MoveRight();
  ArmTurm.MoveDelta(0, 150);
  Gabel.MoveLeft();
  ArmTurm.MoveTo(0, 220);
  Gabel.MoveRight();
  ArmTurm.MoveDelta(0, -150);
  Gabel.MoveLeft();
  BelegtListe[holPos] = false;
}

Danach gehts dann wieder wie gehabt. Am Schluß wird aber noch die BelegtListe upgedated.

 

Downloads

Die hier vorgestellten Programme sind im Päckchen HochRegal zusammengefaßt.

Stand : 13.04.2011