# Het hulpmiddel Scriptbouwer

Toepassingen in KDE kunnen worden bestuurd vanuit een ander programma, vanaf de opdrachtregel in een tekstscherm, of met behulp van een shellscript, waarbij het "Desktop Communication Protocol" (DCOP) wordt gebruikt. In KStars wordt dit gebruikt voor het vastleggen van tamelijk complex gedrag in een script, dat daarna elk moment kan worden afgespeeld. Men kan hiervan bijvoorbeeld gebruik maken voor het maken van een demonstratie in de klas, om een astronomisch begrip toe te lichten.

Het probleem met DCOP-scripts is dat het schrijven ervan een beetje lijkt op programmeren, waartegen iemand zonder programmeerervaring kan opzien. Het hulpmiddel Scriptbouwer heeft een GUI-interface, waarin u alleen maar hoeft te klikken om DCOP-scripts te maken voor KStars, waarmee het maken van complexe scripts erg eenvoudig wordt.

## Inleiding tot de Scriptbouwer

Voor de uitleg hoe de Scriptbouwer moet worden gebruikt, geef ik een korte inleiding tot alle GUI-componenten; als u meer wilt weten, kunt u de "Wat is dit"-functie gebruiken.

Het hulpmiddel Scriptbouwer
Het hulpmiddel Scriptbouwer

In de schermafbeelding hierboven ziet u de Scriptbouwer. Het vak links is het vak Huidige script; hierin ziet u de lijst van opdrachten in de huidige script. Het vak rechts is de Functiebrowser, hierin ziet u een lijst van alle beschikbare functies. Onder de Functiebrowser is een klein paneel met informatie over de in de Functiebrowser geselecteerde functie. In het paneel onder het vak "Huidige script"ziet u de Functieargumenten; als een functie in het vak "Huidigescript" is geselecteerd, vindt u hier de gegevens over de eventuele argumenten die deze functie nodig heeft.

Aan de bovenkant van het venster ziet u een rij knoppen waarmee u bewerkingen op de hele script kunt uitvoeren. Van links naar rechts zijn dit: Nieuw Script, Script openen, Script opslaan, Script opslaan als..., en Script testen. Het is duidelijk waar deze knoppen voor dienen, behalve misschien de laatste. Als u op de knop Script testen drukt, zal geprobeerd worden om de huidige script uit te voeren in het hoofdvenster van KStars. Het venster van de Scriptbouwer moet uit de weg worden verplaatst, om het resultaat te kunnen zien.

In het midden van het venster is een rij knoppen voor bewerkingen op de individuele scriptfuncties. Van boven naar beneden zijn dit de knoppen: Functie toevoegen, Functie verwijderen, Functie kopiëren, Omhoog, en Omlaag. Met de knop Functie toevoegen voegt u de in de Functiebrowser geselecteerde functie toe aan het vak "Huidige script" (u kunt ook de functie toevoegen door erop te dubbelklikken). Met de overige knoppen voert u bewerkingen uit op de functie die in het vak "Huidig script" is geselecteerd: verwijderen, kopiëren, of verplaatsen in de huidige script.

## Gebruik van de Scriptbouwer

Om het gebruik van de Scriptbouwer toe te lichten, geven we hier een klein leerzaam voorbeeld waarin we een script maken dat de maan volgt, terwijl de klok sneller loopt.

Als we de maan willen volgen, moeten we er eerst op focussen. Daarvoor gebruiken we de functie lookToward (kijk in de richting van). Kies deze functie in de Functiebrowser, en bekijk de documentatie in het paneel onder de browser. Druk op de knop Functie toevoegen om deze functie toe te voegen in het vak "Huidige script". In het paneel "Functieargumenten" ziet u nu een comboveld met de tekst dir, wat direction (richting) betekent. Dit is de kijkrichting in het beeldscherm. Het comboveld bevat alleen de hoofd- en tussenstreken van het kompas, en niet de maan of andere objecten. U kunt of Maan met de hand invullen in het comboveld, of op de knop Object drukken om het venster Object zoeken te kunnen gebruiken om hierin de Maan te selecteren uit de lijst van objecten met een naam. Merk op, dat zoals gewoonlijk, het centreren op een object het volgen automatisch inschakelt, het is dus niet nodig om de functie setTracking (volgen aanzetten) toe te voegen na lookToward.

Nu we ervoor hebben gezorgd dat de kijkrichting op de maan wordt ingesteld, willen we de tijd sneller laten lopen. Gebruik hiervoor de functie setClockScale (Kloksnelheid instellen). Voeg deze functie toe aan de script door erop te dubbelklikken in de Functiebrowser. Het paneel "Functieargumenten" heeft een tijdstap-spinveld om de gewenste tijdstap voor de simulatieklok te kiezen. Verander de tijdstap in 3 uur.

Goed, we hebben nu de kijkrichting op de maan ingesteld, en de klok versneld. Nu willen we dat de script enkele seconden wacht, terwijl in het beeld de maan wordt gevolgd. Voeg de functie waitFor (wacht op) toe aan de script, en gebruik het paneel "Functieargumenten" om aan te geven dat er 20 seconden moet worden gewacht alvorens verder te gaan.

Tenslotte zetten we de tijdstap van de klok terug naar de normale waarde van 1 seconde. Voeg de functie setClockscale nog een keertje toe, met als argument 1 sec.

Eigenlijk zijn we nu nog niet klaar. We moeten er zeker van zijn dat er op het scherm equatoriale coördinaten worden gebruikt, voordat de script de maan versneld gaat volgen. Anders, als horizontale coördinaten worden gebruikt, zal het scherm zeer snel veranderen over grote hoeken op de momenten dat de maan opkomt of ondergaat. Dit is erg verwarrend, en kan worden vermeden door de weergaveoptie UseAltAz (gebruik HgteAz) op "false" (onwaar) in te stellen. Om een weergaveoptie te veranderen, gebruikt u de functie changeViewOption (verander de weergaveoptie). Voeg deze functie toe aan de script, en bestudeer het paneel "Functieargumenten". Er is een comboveld met een lijst van alle weergaveopties die door changeViewOption kunnen worden veranderd. Omdat we weten dat we de UseAltAz-optie moeten hebben, kunnen we die gewoon kiezen in het comboveld. Maar de lijst is erg lang, en er is geen uitleg bij elke regel. Het is daarom wellicht eenvoudiger om op de knop Lijst doorbladeren te drukken, waardoor een venster wordt geopend met een lijst van alle weergaveopties, ingedeeld naar onderwerp. Er is bovendien uitleg bij elke optie, en het gegevenstype van de waarde van elke optie. We vinden "UseAltAz" in de categorie Hemelkaartopties. Kies het en druk op de knop OK, en het zal worden gekozen in het combinatieveld van het paneel "Functieargumenten". Tenslotte maakt u de waarde ervan false of 0.

Nog een stap: het veranderen van "UseAltAz" aan het eind van de script zal ons niet helpen, dit moet gebeuren voor alles wat er gebeurt. Dus kies deze functie in het vak "Huidige script" en druk op de knop Omhoog totdat het de eerste functie in de script is.

Nu dat we met de script klaar zijn, moeten we die nog opslaan op de schijf. Druk op de knop Script opslaan. Hierdoor wordt eerst een venster geopend, waarin u een naam kunt invullen van de script, en uw naam als de auteur. Vul als naam in Volgen van de Maan, en uw naam als auteur, en druk op OK. U zult daarna de standaarddialoog "Bestand opslaan" van &kde; zien. Voer een bestandsnaam in voor de script. Merk op dat de extensie .kstars automatisch wordt toegevoegd mocht u die vergeten. Als u nieuwsgierig bent, kunt u met elke tekstverwerker het scriptbestand bekijken.

Nu we een script hebben gemaakt, kunnen we die op een aantal manieren laten werken. U kunt de script uitvoeren vanaf de opdrachtregel in een tekstscherm, als er een KStars draait. U kunt ook de script uitvoeren vanuit KStars, met Script uitvoeren in het menu Bestand.

## Apparaatautomatisering met INDI

De tijdsindeling en het automatiseren wordt ondersteund voor alle apparaten die voldoen aan de eisen van INDI. Met de Scriptbouwer van &kstars; kunt u elk aantal apparaten coördineren voor het uitvoeren van complexe taken. Dit kan worden bereikt met behulp van de INDI DCOP-interface van &kstars; waarmee u de beschikking heeft over verschillende groepen van functies voor wat u wenst te gaan doen. De INDI DCOP-functies kunnen worden verdeeld in vier verschillende groepen. In het volgende vindt u een beschrijving van deze functies en hun argumenten, zoals die worden ondersteund in KStars. Het wordt sterk aangeraden om het hoofdstuk Concepten van INDI te lezen omdat de belangrijkste concepten van INDI overal in deze beschrijving zullen worden gebruikt.

1. Algemene apparaatfuncties: Functies voor het aanzetten/afsluiten van apparaten etc.

   - `startINDI (QString apparaatNaam, bool gebruikLokaal)` : Het aanzetten van een dienst van INDI als lokaal of als server.

   - `shutdownINDI (QString apparaatNaam)` : Afsluiten van de dienst INDI.

   - `switchINDI(QString apparaatNaam, bool aanzetten)` : Aan- of afkoppelen van een INDI-apparaat.

   - `setINDIPort(QString apparaatNaam, QString poort)` : De verbindingspoort van het apparaat instellen.

   - `setINDIAction(QString apparaatNaam, QString actie)` : Een INDI-actie activeren. De actie kan elk element zijn van een schakeleigenschap

   - `waitForINDIAction(QString apparaatNaam, QString actie)` : De scriptuitvoering onderbreken totdat een opgegeven actieeigenschap de OK-status retourneert.

2. Telescoopfuncties: Functies voor de besturing van de telescoopbeweging en -status.

   - `setINDIScopeAction(QString apparaatNaam, QString actie)` : Voor het instellen van de telescoopmodus of -actie. Beschikbare opties zijn SLEW, TRACK, SYNC, PARK, and ABORT (verplaatsen, volgen, synchroniseren, parkeren en afbreken).

   - `setINDITargetCoord(QString apparaatNaam, double RK, double DEC)` : Voor het instellen van de "JNow"-doelcoördinaten van de telescoop: RK en DEC.

     Noot vertaler: "Jnow" betekent: epoche van dit moment. Een telescoop moet noodzakelijkerwijs werken met de coördinaten die voor precessie zijn gecorrigeerd naar die van het moment waarop de telescoop wordt gebruikt.

   - `setINDITargetName(QString apparaatNaam, QString objectNaam)` : Voor het instellen van de "JNow"-doelcoördinaten van de telescoop naar die van objectNaam. KStars zoekt objectNaam op in zijn gegevensbank en als die wordt gevonden worden de RK en Dec daar opgehaald.

     Noot vertaler: "Jnow" betekent: epoche van dit moment. Een telescoop moet noodzakelijkerwijs werken met de coördinaten die voor precessie zijn gecorrigeerd naar die van het moment waarop de telescoop wordt gebruikt.

   - `setINDIGeoLocation(QString apparaatNaam, double lengte, double breedte)` : Het instellen van de geografische locatie van de telescoop volgens de opgegeven coördinaten. De lengte wordt gerekend vanaf de Meridiaan van Greenwich , VK, in oostelijke richting. Maar, hoewel het gewoon is om voor westelijke lengtes negatieve waarden te gebruiken, vereist INDI waarden voor de lengtes tussen 0 en 360 graden. Dus bij een negatieve lengte moet er voor INDI 360 graden worden bijgeteld. De lengte van Calgary, Canada, bijvoorbeeld, is volgens KStars: -114 04 58 (negatief, dus west), en de breedte: 51 02 58. Dus voor INDI moeten wij bij de negatieve lengte 360 graden optellen: -114,083 + 360 = 245,917 graden (-114,083 is de in decimale graden omgezette lengte -114 04 58, waarbij 04 minuten 58 seconden = 4/60 + 58/3600 = 0,082777... graden).

   - `setINDIUTC(QString apparaatNaam, QString UTCDatumTijd)` : Voor het instellen van de UTC-datum en -tijd in ISO 8601 formaat. Dit formaat is YYYY-MM-DDTHH:MM:SS (bijv. 2004-07-12T22:05:32).

3. Camera/CCD-Functies voor de besturing van de eigenschappen en status van de camera/CCD.

   - `setINDICCDTemp(QString apparaatNaam, int temp)` : Voor het instellen van de beoogde temperatuur van de CCD-chip in graden Celsius.

   - `setINDIFrameType(QString apparaatNaam, QString type)` : Voor het instellen van het belichtingstype van de CCD. Beschikbare opties zijn FRAME_LIGHT, FRAME_BIAS, FRAME_DARK, and FRAME_FLAT (deze termen niet vertaald, daar de betekenis ervan bekend moet zijn om er zinvol mee te werken)

     Dark frame: Belichting met gesloten sluiter. Flat frame: Belichting op een egaal verlicht oppervlak. Bias frame: Idem, maar voor elke pixel hetzelfde opgeteld. Light frame: het eigenlijke beeld.

     Dark, Flat en Bias frames dienen om het beeld te kunnen verbeteren.

     Ik raad aan om met bijvoorbeeld Google informatie hierover te vinden, maar kon zelf nauwelijks Nederlandse pagina's vinden (vert.)

   - `startINDIExposure(QString apparaatNaam, int tijdsduur)` : Voor het instellen van de belichting van de CCD/Camera gedurende een tijdsduur in seconden.

4. Focusserfuncties: Functies voor de besturing van de beweging en de status van de focusser (scherpstelinrichting).

   - `setINDIFocusSpeed(QString apparaatNaam, QString actie)` : Voor het instellen van de snelheid van de focusser. Beschikbare opties zijn FOCUS_HALT, FOCUS_SLOW, FOCUS_MEDIUM, and FOCUS_FAST (focus_halt, _langzaam, _middel en _snel).

   - `setINDIFocusTimeout(QString apparaatNaam, int tijdsduur)` : Voor het instellen van de duur in seconden van enige volgende startINDIFocus-bewerking.

   - `startINDIFocus(QString apparaatNaam, int focusRichting)` : Beweegt de focuser of naar binnen (focusRichting = 0) of naar buiten (focusRichting = 1). De snelheid en de tijdsduur van deze bewerking worden ingesteld met de functies `setINDIFocusSpeed()` en `setINDIFocusTimeout()`.

5. Filterfuncties: Functies voor de besturing van de filterpositie.

   - `setINDIFilterNum(QString ApparaatNaam, int filter_num)` : Verander de filterpositie naar `filter_num`. De gebruiker kan aliassen toekennen aan filternummers in het dialoogvak van INDI instellen in het menu Apparaten (bijv. Filter 1 = Red (rood), Filter 2 = Green (groen) .. enz.).

Merk op dat in alle functies van INDI de naam van het apparaat het eerste argument is. Hierdoor kunnen in een script verschillende commando's voorkomen die naar verschillende INDI-apparaten worden gestuurd. In het hulpmiddel Scriptbouwer zijn twee opties aanwezig die het maken en het bewerken van INDI-scripts vereenvoudigen:

- `Voeg waitForINDIAction toe na elke INDI-actie` : Indien aangevinkt zal Scriptbouwer automatisch `waitForINDIAction()` toevoegen na elke actie die wordt herkend. Bijvoorbeeld, als u de functie `switchINDI()`aan de script toevoegt met deze optie aangevinkt, zal de Scriptbouwer "waitForINDIAction CONNECTION" in het scriptbestand toevoegen direct achter `switchINDI()`. Hierdoor zal de script pauseren na de opdracht `switchINDI()` totdat `switchINDI()` de OK status retourneert (d.w.z. nadat de verbinding met het apparaat gelukt is). Het is van groot belang te weten dat de Scriptbouwer niet automatisch `waitForINDIAction()` kan toevoegen voor algemene acties die zijn toegevoegd met behulp van de functie `setINDIAction()`. Dit komt omdat KStars van algemene acties niet de eigenschappen van de "parent" (ouder) kan bepalen. Daarom moet u, indien gewenst, in dat geval zelf `waitForINDIAction()` toevoegen achter algemene acties.

- `Gebruik INDI-apparaatnaam opnieuw` : Indien aangevinkt wordt in het veld voor de apparaatnaam van alle volgende functies automatisch de laatste apparaatnaam ingevuld. De laatste apparaatnaam wordt steeds ingesteld nadat de functie `startINDI()` wordt toegevoegd aan de huidige script. Indien met meerdere apparaten wordt gewerkt wordt u aangeraden deze optie uit te zetten.

Nu zijn we zover dat we een demoscript kunnen maken voor de besturing van een LX200 GPS-telescoop, samen met de CCD-camera van Finger Lakes. Onze opdracht is eenvoudig. We zullen de telescoop naar Mars laten bewegen en Mars laten volgen, daarna vragen we de camera om drie opnamen te maken, ieder gedurende 10 seconden, met een tussenpoos van 20 seconden.

Omdat de INDI DCOP-interface geen directe terugkoppeling (feedback) geeft over de voortgang, waarde of status van de bewerkingen en parameters van het apparaat (behalve `waitForINDIAction()`), is de automatisering van apparaten in KStars gelijksoortig aan open-lus (open-loop) besturingssystemen. In zulke systemen bestaat er geen directe terugkoppeling om de voortgang van het systeem te meten en voor fouten te corrigeren. Daarom moeten automatiseringsscripts zorgvuldig worden ontworpen. Zij moeten alle uitvoerig worden getest voordat ze kunnen worden gebruikt.

Noot vertaler: zie ook bladzij 91 op http://wwwhome.math.utwente.nl/~poldermanjw/onderwijs/156057/diktaat.pdf

Het hulpmiddel Scriptbouwer
Het hulpmiddel Scriptbouwer

In het bovenstaande schermbeeld ziet u de demoscript. Merk op dat we de optie `"Voeg waitForINDIAction toe na elke INDI-actie"` hebben aangevinkt en de optie `"Gebruik INDI-apparaatnaam opnieuw"` uitgevinkt. De eerste functie die moet worden toegevoegd is `startINDI()`, zoals u hierboven kunt zien. We willen onze apparaten als lokale apparaten laten werken, en hoeven dus niet de dienstmodus te veranderen in het venster voor de functieargumenten. We typen de apparaatnaam in, te beginnen met de telescoop "LX200 GPS". We herhalen dit voor de camera "FLI CCD". Daarna komt de functie `waitFor()`. In het algemeen wordt aangeraden om direct na `startINDI()` de functie `waitFor()` te gebruiken om de script gedurende 1-5 seconden te laten wachten. Hierdoor bent u er zeker van dat alle eigenschappen goed worden geïnstalleerd en klaar zullen zijn voor het ontvangen van een commando. Het is ook nuttig bij de besturing van apparaten op afstand omdat het ophalen en het installeren van eigenschappen dan enige tijd kunnen vergen. Met de volgende functie, `switchINDI()` wordt elk apparaat aangekoppeld.

Omdat de optie `"Voeg waitForINDIAction toe na elke INDI-actie"` is aangevinkt, hoeven we deze niet meer zelf toe te voegen na `switchINDI()` om er zeker van te zijn dat de script alleen verder wordt uitgevoerd na een succesvolle aankoppeling van de apparaten, omdat de Scriptbouwer dit automatisch voor ons doet wanneer we de script opslaan. Nu zullen we het volgen van de telescoop gaan instellen, klik op de functie `setINDIScopeAction()` en selecteer TRACK (volgen). Merk op dat we het volgen door de telescoop moeten instellen voordat de te volgen coördinaten worden opgegeven. De functie `setINDIScopeAction()` dient hier het gemak, omdat in dit voorbeeld het een algemene functie `setINDIAction()` uitvoert gevolgd door het sleutelwoord TRACK. Echter, het nut van het gebruik van `setINDIAction()` is dat KStars automatisch de functie `waitForINDIAction()` kan toevoegen daar waar dat nodig is. Dit gemak is niet automatisch beschikbaar bij algemene acties, zoals we al hebben besproken.

Vervolgens gebruiken we de functie `setINDITargetName()` en stellen die in op Mars. Tenslotte worden in de laatste paar stappen afbeeldingen belicht gedurende 10 seconden met de functie `startINDIExposure()`, waarna 20 seconden wordt gewacht tussen de belichtingen met de functie `waitFor()` met als argument 20.

We kunnen nu onze script opslaan en het op ieder moment uitvoeren. Het opgeslagen script ziet er zo uit (als u bash gebruikt als opdrachtvertaler (shell)):

>     #!/bin/bash
>         #KStars DCOP script: Demoscript
>         #door Jasem Mutlaq
>         #laatst gewijzigd: Do 6 Jan 2005 09:58:26
>         #
>         KSTARS=`dcopfind -a 'kstars*'`
>         MAIN=KStarsInterface
>         CLOCK=clock#1
>         dcop $KSTARS $MAIN  startINDI "LX200 GPS" true
>         dcop $KSTARS $MAIN  startINDI "FLI CCD" true
>         dcop $KSTARS $MAIN  waitFor 3
>         dcop $KSTARS $MAIN  switchINDI "LX200 GPS" true
>         dcop $KSTARS $MAIN  waitForINDIAction "LX200 GPS" CONNECTION
>         dcop $KSTARS $MAIN  switchINDI "FLI CCD" true
>         dcop $KSTARS $MAIN  waitForINDIAction "FLI CCD" CONNECTION
>         dcop $KSTARS $MAIN  setINDIScopeAction "LX200 GPS" TRACK
>         dcop $KSTARS $MAIN  waitForINDIAction "LX200 GPS" ON_COORD_SET
>         dcop $KSTARS $MAIN  setINDITargetName "LX200 GPS" Mars
>         dcop $KSTARS $MAIN  waitForINDIAction "LX200 GPS" EQUATORIAL_EOD_COORD
>         dcop $KSTARS $MAIN  startINDIExposure "FLI CCD" 10
>         dcop $KSTARS $MAIN  waitForINDIAction "FLI CCD" EXPOSE_DURATION
>         dcop $KSTARS $MAIN  waitFor 20
>         dcop $KSTARS $MAIN  startINDIExposure "FLI CCD" 10
>         dcop $KSTARS $MAIN  waitForINDIAction "FLI CCD" EXPOSE_DURATION
>         dcop $KSTARS $MAIN  waitFor 20
>         dcop $KSTARS $MAIN  startINDIExposure "FLI CCD" 10
>         dcop $KSTARS $MAIN  waitForINDIAction "FLI CCD" EXPOSE_DURATION

In de INDI-bibliotheek zijn robuuste hulpmiddelen te vinden voor het schrijven van scripts, waardoor het voor ontwikkelaars mogelijk is om zeer complexe scripts samen te stellen. Voor nadere informatie zie INDI Developer Manual (Handboek voor de INDI-ontwikkelaar, in het Engels).