halcmd zeichnet sich durch die Angabe von Komponenten und Verbindungen aus, aber diese Skripte bieten keine Berechnungsmöglichkeiten. Infolgedessen sind INI-Dateien in der Klarheit und Kürze, die mit höheren Sprachen möglich ist, eingeschränkt.

Die haltcl-Funktionalität bietet die Möglichkeit, Tcl-Skripte und ihre Funktionen für Berechnungen, Schleifen, Verzweigungen, Prozeduren usw. in INI-Dateien zu verwenden. Um diese Funktionalität zu nutzen, verwenden Sie die Tcl-Sprache und die Erweiterung .tcl für HAL-Dateien.

Die Erweiterung .tcl wird von dem Hauptskript (linuxcnc) verstanden, das INI-Dateien verarbeitet. Haltcl-Dateien werden im HAL-Abschnitt von INI-Dateien identifiziert (genau wie HAL-Dateien).

Beispiel
[HAL]
HALFILE = conventional_file.hal
HALFILE = tcl_based_file.tcl

Bei entsprechender Sorgfalt können HAL- und Tcl-Dateien miteinander vermischt werden.

1. Kompatibilität

Die in HAL-Dateien verwendete halcmd-Sprache hat eine einfache Syntax, die eigentlich eine Teilmenge der leistungsfähigeren Allzweck-Skriptsprache Tcl ist.

2. Haltcl-Befehle

Haltcl-Dateien verwenden die Tcl-Skriptsprache, die mit den spezifischen Befehlen der LinuxCNC-Hardware-Abstraktionsschicht (HAL) erweitert wird. Die HAL-spezifischen Befehle sind:

addf, alias,
delf, delsig,
getp, gets
ptype,
stype,
help,
linkpp, linkps, linksp, list, loadrt, loadusr, lock,
net, newsig,
save, setp, sets, show, source, start, status, stop,
unalias, unlinkp, unload, unloadrt, unloadusr, unlock,
waitusr

Für die Befehle gets und list gibt es zwei Sonderfälle aufgrund von Konflikten mit eingebauten Tcl-Befehlen. Für haltcl muss diesen Befehlen das Schlüsselwort hal vorangestellt werden:

halcmd   haltcl
------   ------
gets     hal gets
list     hal list

3. Haltcl INI-Datei-Variablen

Auf Variablen in INI-Dateien kann sowohl mit halcmd als auch mit haltcl zugegriffen werden, allerdings mit unterschiedlicher Syntax. LinuxCNC INI-Dateien verwenden SECTION- und ITEM-Spezifikationen, um Konfigurationselemente zu identifizieren:

[SECTION_A]
ITEM1 = value_1
ITEM2 = value_2
...
[SECTION_B]
...

Die Werte der INI-Datei sind durch Textersetzung in HAL-Dateien in folgender Form zugänglich:

[SECTION]ITEM

Die gleichen Werte der INI-Datei sind in Tcl-Dateien in Form einer globalen Tcl-Array-Variable zugänglich:

$::SECTION(ITEM)

Zum Beispiel, ein INI-Datei Element wie:

[JOINT_0]
MAX_VELOCITY = 4

wird in HAL-Dateien für halcmd als [JOINT_0]MAX_VELOCITY ausgedrückt
und als $::JOINT_0(MAX_VELOCITY) in Tcl-Dateien für haltcl.

Da INI-Dateien das gleiche ITEM in der gleichen SECTION mehrfach wiederholen kann, ist $::SECTION(ITEM) eigentlich eine Tcl-Liste jedes einzelnen Wertes.

Wenn es nur einen Wert gibt und dieser ein einfacher Wert ist (alle Werte, die nur aus Buchstaben und Zahlen ohne Leerzeichen bestehen, gehören zu dieser Gruppe), dann ist es möglich, $::SECTION(ITEM) so zu behandeln, als ob es keine Liste wäre.

Wenn der Wert Sonderzeichen enthalten könnte (Anführungszeichen, geschweifte Klammern, eingebettete Leerzeichen und andere Zeichen, die in Tcl eine besondere Bedeutung haben), dann ist es notwendig, zwischen der Liste der Werte und dem ersten (und möglicherweise einzigen) Wert in der Liste zu unterscheiden.

In Tcl wird dies als [lindex $::SECTION(ITEM) 0] geschrieben.

Beispiel: Bei den folgenden INI-Werten

[HOSTMOT2]
DRIVER=hm2_eth
IPADDR="10.10.10.10"
BOARD=7i92
CONFIG="num_encoders=0 num_pwmgens=0 num_stepgens=6"

Und diesem loadrt-Befehl:

loadrt $::HOSTMOT2(DRIVER) board_ip=$::HOSTMOT2(IPADDR) config=$::HOSTMOT2(CONFIG)

Ist dieses der eigentliche Befehl, der ausgeführt wird:

loadrt hm2_eth board_ip={"10.10.10.10"} config={"num_encoders=0 num_pwmgens=0 num_stepgens=6"}

Dies schlägt fehl, weil loadrt die geschweiften Klammern nicht erkennt.

Um die Werte so zu erhalten, wie sie in der INI-Datei eingegeben wurden, schreiben Sie die loadrt-Zeile wie folgt um:

loadrt $::HOSTMOT2(DRIVER) board_ip=[lindex $::HOSTMOT2(IPADDR) 0] config=[lindex $::HOSTMOT2(CONFIG) 0]

4. Konvertieren von HAL-Dateien in Tcl-Dateien

Vorhandene HAL-Dateien können durch manuelle Bearbeitung in Tcl-Dateien konvertiert werden, um die oben genannten Unterschiede zu berücksichtigen. Der Prozess kann mit Skripten automatisiert werden, die diese Substitutionen verwenden.

[SECTION]ITEM ---> $::SECTION(ITEM)
gets          ---> hal gets
list          ---> hal list

5. Haltcl Anmerkungen

In haltcl wird das Argument value für die Befehle sets und setp implizit als Ausdruck in der Tcl-Sprache behandelt.

Beispiel
# Verstärkung für die Umrechnung von Grad/Sekunde in Einheiten/Minute für den JOINT_0-Radius festlegen
setp scale.0.gain 6.28/360.0*$::JOINT_0(radius)*60.0

Leerzeichen im bloßen Ausdruck sind nicht erlaubt, verwenden Sie dafür Anführungszeichen:

setp scale.0.gain "6.28 / 360.0 * $::JOINT_0(radius) * 60.0"

In anderen Zusammenhängen, wie z. B. bei loadrt, müssen Sie den Tcl "expr"-Befehl ([expr {}]) ausdrücklich für Berechnungsausdrücke verwenden.

Beispiel
loadrt motion base_period=[expr {500000000/$::TRAJ(MAX_PULSE_RATE)}]

6. Haltcl Beispiele

Betrachten Sie das Thema "Stepgen Headroom". Die Software stepgen läuft am besten mit einer Beschleunigungsbeschränkung, die "ein bisschen höher" ist als die vom Bewegungsplaner verwendete. Bei der Verwendung von halcmd-Dateien erzwingen wir daher, dass INI-Dateien einen manuell berechneten Wert haben.

[JOINT_0]
MAXACCEL = 10.0
STEPGEN_MAXACCEL = 10.5

Mit haltcl können Sie Tcl-Befehle verwenden, um die Berechnungen durchzuführen, und das STEPGEN_MAXACCEL-Element in der INI-Datei ganz eliminieren:

setp stepgen.0.maxaccel $::JOINT_0(MAXACCEL)*1.05

Eine weitere Funktion von haltcl ist die Schleifenbildung und das Testen. Viele Simulatorkonfigurationen verwenden zum Beispiel die HAL-Dateien "core_sim.hal" oder "core_sim9.hal". Diese unterscheiden sich durch die Anforderung, mehr oder weniger Achsen anzuschließen. Der folgende haltcl-Code würde für jede Kombination von Achsen in einer trivkins-Maschine funktionieren.

# Anlegen von position, velocity (Geschwindigkeit) and acceleration (Beschleunigung) Signalen für jede Achse
set ddt 0
for {set jnum 0} {$jnum < $::KINS(JOINTS)} {incr jnum} {
  # 'list pin' gibt eine leere Liste zurück, wenn der Pin nicht existiert
  if {[hal list pin joint.${jnum}.motor-pos-cmd] == {}} {
    continue
  }
  net ${jnum}pos joint.${jnum}.motor-pos-cmd => joint.$axno.motor-pos-fb \
                                             => ddt.$ddt.in
  net ${axis}vel <= ddt.$ddt.out
  incr ddt
  net ${axis}vel => ddt.$ddt.in
  net ${axis}acc <= ddt.$ddt.out
  incr ddt
}
puts [show sig *vel]
puts [show sig *acc]

7. Haltcl Interaktiv

Der Befehl halrun erkennt haltcl-Dateien. Mit der Option -T kann haltcl interaktiv als Tcl-Interpreter ausgeführt werden. Diese Fähigkeit ist nützlich zum Testen und für eigenständige HAL-Anwendungen.

Beispiel
$ halrun -T haltclfile.tcl

8. Haltcl-Verteilungsbeispiele (sim)

Das Verzeichnis configs/sim/axis/simtcl enthält eine INI-Datei, die eine .tcl-Datei verwendet, um eine haltcl-Konfiguration in Verbindung mit der Verwendung der twopass-Verarbeitung zu demonstrieren. Das Beispiel zeigt die Verwendung von Tcl-Prozeduren, Schleifen, die Verwendung von Kommentaren und die Ausgabe auf dem Terminal.