JavaScript
Scripte in der FVA-Workbench werden mit der Skriptsprache JavaScript (JS) geschrieben. JS wird außerhalb der FVA-Workbench hauptsächlich für die Programmierung dynamischer Internetseiten verwendet. Der Sprachkern von JS heißt ECMAScript und enthält die Funktionen von JS, die sowohl für Websites als auch in der FVA-Workbench benutzt werden können.
Anmerkung
Die Funktionsvielfalt von JavaScript ist zu groß, um sie innerhalb der KnowledgeBase vollständig darzustellen. Es werden daher im Folgenden nur die wichtigsten Sprachelemente behandelt. Diverse Internetseiten bieten aber für jedes vorstellbare JS--Problem eine Lösung an. Alle JS-Funktionen, die nicht spezifisch für die Manipulation von Webseiten gedacht sind, können auch im Scripting der FVA-Workbench eingesetzt werden.
Datentypen
Die Attribute, in denen Nutzereingaben und Berechnungsergebnisse gespeichert werden, haben folgende Datentypen:
Datentyp | Typbezeichner | Daten | Beispielattribut (ID) |
---|---|---|---|
Wahrheitswert | Boolean | true oder false | use_fem_part (FEM Steifigkeit berücksichtigen) |
Zahl | Double | 3.14159 | iso 6336 application factor (Anwendungsfaktor) |
Zahl mit Einheit | TechValue | 3.14159 mm | center_distance (Achsabstand) |
Zeichenkette | String | "This is text" | comp_remarks (Komponenten-Vermerke) |
Liste | Array | [0.12, 2.34, 7.83, 2.33] | force in mesh direction (Breitenlastverteilung) |
Liste von Listen | Matrix | [ [1.2, 3.0, 4.6], [0.2, 6.4, 2.1], [3.1, 1.5, 9.5] ] | result_matrix_pressure_distribution_values (Pressungsverteilung) |
Spezialfall Combo-Attribute
Im Eingabeeditor der FVA-Workbench gibt es an vielen Stellen Drop-Down Listen, bei denen der Anwender aus mehreren Einträgen auswählen kann. Diese Auswahl wird in sogenannten Combo-Attributen gespeichert. Der Datentyp solcher Combo-Attribute kann entweder String, Integer oder Double sein.
Bei Combo-Attributen ist intern eine Werteliste hinterlegt, bei der jedem Wert genau eine Auswahlmöglichkeit zugeordnet ist.
setAttr("ratio_X1_X2", stageID, 6, EDAT);
Beispielscript: Combo-Attribut "Aufteilung Profilverschiebung" auf den Wert 6 für "Gleiche Wälzpressung" setzen.
Gültigkeitsbereich von Variablen
Der Gültigkeitsbereich einer Variablen beschreibt, wo eine Variable innerhalb eines Scripts verfügbar ist und benutzt werden kann.
Variablen in JS sind entweder global oder lokal. Globale Variablen werden über das Schlüsselwort var deklariert. var myVariable = 3.14
Auf globale Variablen kann von jeder Stelle des Scripts aus zugegriffen werden. Dies kann aber schnell zu Fehlern führen, da Variablen doppelt vergeben oder überschrieben werden können.
Lokale Variablen werden über das Schlüsselwort let deklariert. let myVariable = 3.14
Auf lokale Variablen kann nur innerhalb des aktuellen Codeblocks zugegriffen werden.
Tipp
Um Fehlerquellen zu minimieren, sollten Variablen in den meisten Fällen mit dem Schlüsselwort let
deklariert werden.
Beispiel - Variable global deklarieren
1for(var i=0; i<10; i++){ 2println(i); }
for-Schleife, in der die Zählvariable i global mit var definiert wird. | |
Da i global deklariert wurde, wird 10 auf dem Scripting-Monitor ausgegeben. |
Beispiel - Variable lokal deklarieren
1for(let i=0; i<10; i++){ 2println(i); }
Mathematische Funktionen
JS bietet eine Reihe von mathematischen Funktionen, die im Scripting der FVA-Workbench angewendet werden können:
Funktion | Rückgabewert |
---|---|
Math.abs(a) | Positiver Wert von a |
Math.ceil(a) | Nächsthöhere ganze Zahl von a |
Math.floor(a) | Nächstniedrigere ganze Zahl von a |
Math.round(a) | Kaufmännisch gerundete Ganzzahl |
Math.max(a,b) | Größere von zwei Zahlen a, b |
Math.min(a,b) | Kleinere von zwei Zahlen a, b |
Math.max.apply(null, array) | Größte Zahl in einem Array |
Math.min.apply(null, array) | Kleinste Zahl in einem Array |
Math.random() | Zufällige Zahl zwischen 0 und 1 |
Math.exp(a) | Exponentialwert von a |
Math.pow(a,b) | Zahl a hoch Exponent b |
Math.log(a) | Anwendung des natürlichen Logarithmus auf a |
Math.sqrt(a) | Quadratwurzel von a |
Math.sin(a) | Sinus von a |
Math.cos(a) | Cosinus von a |
Math.tan(a) | Tangens von a |
Math.asin(a) | Arcussinus von a |
Math.acos(a) | Arcuscosinus von a |
Math.atan(a) | Arcustangens von a |
Operatoren
Vergleichsoperatoren werden in logischen Anweisungen verwendet, um Gleichheit oder Differenz zwischen Variablen oder Werten zu bestimmen. Logische Operatoren werden benutzt, um zwei oder mehr Bedingungen logisch miteinander zu verketten.
Beispiel - Vergleichs- und logische Operatoren in der Bedingung einer if Anweisung
let age = 17; let country = "germany"; if(age >= 16 && country == "germany"){ println("You are allowed to drink beer"); }
Operator | Beschreibung | Beispiel (x = 3) | Rückgabewert |
---|---|---|---|
== | gleich | x == 2 | false |
!= | ungleich | x != 4 | true |
> | größer | x < 4 | true |
< | kleiner | x > 4 | false |
>= | größer gleich | x >= 3 | true |
<= | kleiner gleich | x <= 4 | false |
Operator | Beschreibung |
---|---|
&& | Beim "und"-Operator müssen beide bzw. alle Bedingungen erfüllt sein, damit die gesamte Bedingung erfüllt ist. |
|| | Beim "oder"-Operator muss nur eine Bedingung erfüllt sein, damit die gesamte Bedingung erfüllt ist. |
! | Der "nicht"-Operator wird wahr, wenn der sich anschließende Ausdruck unwahr ist. |
for-Schleife
Der Schleifenkopf einer for-Schleife enthält eine Zählvariable, eine Fortführungsbedingung sowie eine Anweisung zur Änderung der Zählvariable.
Beispiel - Drehmoment für eine Belastungskomponente von 0 bis 100 in 10er Schritten erhöhen. Nach jeder Erhöhung wird eine Gesamtsystemberechnung durchgeführt.
let gearUnitID = 1; let forceID = 20; for (let i = 0; i <= 100; i+=10){ setAttr("scaled torque", forceID, i, EDAT); runCalcMethod("001_SYSTEM_CALCULATION", gearUnitID); }
Beispiel - Den Namen von jedem Wälzlager im Modell auf dem Scripting-Monitor ausgeben.
let bearings = getCompByType("bearing"); for (let i = 0; i < bearings.length; i++){ println(getCompProperty(bearings[i], "NAME")); }
while-Schleifen
while-Schleife
Die while-Schleife wiederholt Anweisungen, solange die Bedingung am Schleifenbeginn true liefert. Wenn die Bedingung bei der ersten Abfrage nicht true liefert, wird die while-Schleife gar nicht erst ausgeführt.
var i = 0; while (i < 10) { println(i); i = i+1; }
do-while-Schleife
Im Gegensatz zur while-Schleife wird die Schleifenbedingung erst am Ende der Schleife geprüft. Die Schleife wird also mindestens einmal durchlaufen.
var i = 0; do { println(i); i = i+1 }while (i < 10);
forEach-Schleife
Die forEach-Schleife führt eine Anweisung für jedes Element in einem Array aus.
Beispiel - Jeden Wert in einem Array mit 3 multiplizieren und auf dem Scripting-Monitor ausgeben.
let array = [2, 4, 5]; array.forEach(function(element){ println(element * 3); });
Beispiel - Eingabewert (EDAT) für Anwendungsfaktor ISO 6336 für alle Stirnradstufen auf 1.5 setzen.
let cylindricalStages = getCompByType("cylindrical_mesh"); cylindricalStages.forEach(function(element) { setAttr("iso 6336 application factor", element, 1.5, EDAT); });
if/else-Anweisungen
Eine if-Anweisung wird ausgeführt, wenn eine Bedingung wahr (true) wird. Ist die Bedingung falsch (false), dann kann über else eine andere Anweisung ausgeführt werden.
Beispiel - Abfrage der Sicherheit gegen Dauerbruch auf einer Kerbstelle und Ausführung unterschiedlichen Anweisungen je nach Wert.
1let gearUnitID = 1; 2let notchID = 64; 3setAttr("gta_switch_iso_6336_2006", gearUnitID, true, EDAT); 4runCalcMethod("001_SYSTEM_CALCULATION", gearUnitID); 5let safety_SD = getAttr("safety_factor_S_D", notchID, RDAT); 6if (safety_SD >= 1.2){ alert("Success SD = "+safety_SD); 7}else{ alert("Failure SD = "+safety_SD); }
Komponenten-ID der Getriebeeinheit. | |
Komponenten-ID einer Kerbstelle. | |
Gesamtsystem-Schalter "Wellensicherheit nach DIN 743" auf true setzen. | |
Gesamtsystemberechnung durchführen. | |
Variable safety_SD mit dem berechneten (RDAT) Sicherheitswert belegen. | |
Wenn safety_SD >= 1.2, dann Meldungsfenster mit dem Text "Success" und angehängtem Sicherheitswert ausgeben. | |
Ansonsten das Meldungsfenster mit dem Text "Failure" und angehängtem Sicherheitswert ausgeben. |
switch-Anweisung
Die switch-Anweisung wird verwendet, um auf verschiedenen Bedingungen basierende Aktionen durchzuführen. Das break-Schlüsselwort beendet die switch-Anweisung und der entsprechende Wert wird zurückgegeben. Das default-Schlüsselwort definiert die Anweisung, die ausgeführt wird, wenn keiner der Werte übereinstimmt.
Beispiel - In Abhängigkeit vom Modul verschiedene Breitenkorrekturwerte setzen
1let gearID = 30; 2let modificationID = 51; 3let module = getAttr("normal module", gearID, EDAT); 4let amount = 0; 5switch (module) { 6 case 1: amount = 3; break; case 1.5: amount = 3; break; case 2: amount = 5; break; case 2.5: amount = 8; break; case 3: amount = 10; break; case 4: amount = 12; break; case 5: amount = 15; break; case 6: amount = 15; break; case 7: amount = 15; break; case 8: amount = 20; break; case 10: amount = 25; break; 7 default: alert("No modification amount defined for this module"); break; } 8println("Modification Amount: "+amount+" mym"); 9setAttr("sekor_cb_bet", modificationID, amount, EDAT);
Komponenten-ID eines Stirnrades. | |
Komponenten-ID einer Korrekturkomponente auf dem obigen Stirnrad. | |
Variable module mit dem Eingabewert (EDAT) für das Attribut "Normalmodul" auf dem, Stirnrad 30 belegen. | |
Variable amount deklarieren und auf 0 setzen. | |
Switch Anweisung, die module als Vergleichswert benutzt. | |
Wenn module = 1 wird die Variable amount auf 3 gesetzt. | |
Wenn keiner der obigen Fälle zutrifft, wird eine Warnung als Meldungsfenster ausgegeben. | |
Ausgabe des ausgewählten Korrekturbetrags auf dem Scripting-Monitor. | |
Setzen des Eingabewerts (EDAT) von Attribut "Betrag der Breitenballigkeit" auf den Wert in amount. |
try-catch Anweisung
Tritt während der Ausführung eines Scriptes ein Fehler (Exception) auf, wird das Script abgebrochen und die Exception wird auf dem Scripting Monitor ausgegeben.
Die try-catch-Anweisung kann verwendet werden, um Fehler, die während der Laufzeit eines Skripts auftreten, abzufangen, darauf zu reagieren und ggf. das Skript trotz des Fehlers weiter auszuführen.
Dazu wird die Anweisung, in der eine Exception auftreten könnte, von einer try-Anweisung eingerahmt. Wenn eine Ausnahme auftritt, wird die Anweisung in der catch-Anweisung ausgeführt.
Beispiel
In der try-Anweisung wird versucht, eine Berechnung durchzuführen. Die Funktion runCalcMethod() hat als Parameter die Berechnungsmethode und die ID der zu berechnenden Komponente. Nun können zur Laufzeit mehrere Fehler auftreten. Die Methoden-ID oder die Komponenten-ID existieren nicht oder die gewählte Kombination aus beiden kann nicht berechnet werden. Die Exception wird in der catch-Anweisung abgefangen und eine Meldung wird ausgegeben. Das Skript wird dann weiter ausgeführt.
try { runCalcMethod(methodID, compID); } catch (e) { println("Error in the calculation of the component "+compID+" with calculation method "+methodID); } println("Script is continued");
Arrays
Arrays sind Datenstrukturen, bei denen mehrere Werte in einer Variablen gespeichert werden können. Der Zugriff erfolgt über den Index des Elements in eckigen Klammern. Der Index startet bei 0.
let array = [element0, element1, element2];
array[2]
liefert das dritte Element der Liste zurück.
Die Länge, also die Anzahl der Elemente, kann über die Methode .length
abgefragt werden.
array.length
liefert 3 zurück.
Über die Methode array
.push(newElement);
können dem Array weitere Elemente am Ende hinzugefügt werden.
In der FVA-Workbench können Array Zahlen, Strings sowie Komponenten enthalten .
Beispiel - Zugriff auf Arrays
let array = [2, 4, 5]; let result = array[0] + array[2]; println(result);
Die Addition von 2 Elementen eines Arrays ergibt in diesem Beispiel 7.
Beispiel - Abfragen der Arraylänge
let numbers = [1, 2, 3, 4, 5]; for (var i = 0; i < numbers.length; i++) { numbers[i] = numbers[i]*2; } println(numbers);
Die for-Schleife wird so oft durchlaufen, wie das Array numbers Elemente besitzt. In jedem Durchlauf wird das aktuelle Element mit dem Wert des Elements * 2 überschrieben. Nach Abschluss der Schleife enthält numbers folgende Elemente: [2, 4, 6, 8, 10]
Beispiel - Einem Array Elemente hinzufügen
let carmakers = ["BMW", "Mercedes", "Audi", "Edsel"]; carmakers.push("VW"); println(carmakers);
Dem Array carmakers wird per .push ein weiteres Element "VW" angefügt. ["BMW", "Mercedes", "Audi", "Edsel", "VW"]
Beispiel - FVA-Workbench-Komponenten in Arrays speichern
let bearings = getCompByType("bearing"); for (i=0; i < bearings.length; i++){ let catalog_name = getAttr("name", bearings[i], EDAT); println(catalog_name); }
Die Funktion getCompByType() liefert ein Array mit allen Komponenten eines Typs (hier Wälzlager) zurück. In der for-Schleife wird für jedes Element (Lager) des Arrays das Attribut "Katalogname" abgefragt und auf dem Scripting-Monitor ausgegeben.
Text formatieren und zusammenfügen
Für einfache Textformatierungen stehen die inline-Anweisungen Tabulator \t
und Zeilenumbruch \n
zur Verfügung. Für weitergehende Textformatierungen kann die format() -Funktion verwendet werden. Mehrere Texte (Strings) können einfach über den + Operator zusammengefügt werden.
Abbildung 31. Zeilenumbruch | Abbildung 32. Tabulator |
Datum und Zeit ausgeben
Über das JS-Objekt Date kann das aktuelle Jahr, Monat, Tag, Stunde, Minute, Sekunde und Millisekunden ausgegeben werden. Um das Datum abzufragen, wird eine Variable mit new Date();
initialisiert. Die Abfrage erfolgt dann mittels Punktnotation auf dieser Variable.
Beispiel - Ausgabe des kompletten Datums und des aktuellen Monats auf dem Scripting-Monitor
var today = new Date(); println(JSON.stringify(today)); println(today.getMonth());
today | Thu Sep 10 2020 14:00:13 GMT+0200 (CEST) | |
---|---|---|
today.getMonth(); | 8 | liefert 0 - 11 |
today.getFullYear(); | 2020 | YYYY |
today.getDate(); | 10 | liefert 1 - 31 |
today.getDay(); | 4 | Tag der Woche (startet am Sonntag mit 0) |
today.getHours(); | 14 | liefert 0 - 23 |
today.getMinutes(); | 0 | liefert 0 - 59 |
today.getTime(); | 1599739254412 | Millisekunden seit 1.1.1970 |
Kommentare
Kommentare in JS können verwendet werden, um Code zu erklären und lesbarer zu machen. Es kann auch verwendet werden, um Codeabschnitte temporär auszukommentieren, um bspw. alternativen Code auszuprobieren.
1//Comments can be used to explain the code /* 2 Code between /* and */ is not executed */