Kinesimu

Järjestelmäkäsikirja


$Id: jk.html,v 1.55 1996/02/29 11:14:24 jvanhane Exp $

Muutosohjeet

Sisällysluettelo

  • 4. Käsiteluettelo

  • 5. Käyttöohjeet

  • 1. Yleinen esitely

    1.1. Kinemaattinen simulointi

    Kinemaattisen simuloinnin tavoitteena on mahdollistaa erilaisten mekaanisten laitteiden toiminnan tarkasteleminen 3-ulotteisen grafiikan keinoin. Monet CAD-ohjelmistot sisältävätkin mahdollisuuksia kinemaattisten mallien määrittelyyn ja niiden visualisointiin. Samantapaisia menetelmiä sovelletaan myös robottisimulaattoreissa.

    Kinesimu on ohjelmisto, jolla voidaan visualisoida geometristen rajoitusten avulla luotuja kinemaattisia malleja. Kinemaattinen malli muodostuu "linkeistä" ja "liitoksista". Kukin linkki on joukko toisiinsa sidottuja paikallisia koordinaatistoja. Liitos kuvaa kahden eri linkissä olevan koordinaatiston keskinäisen liikkeen vapausasteet.

    Kinesimu tarjoaa


    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |

    1.2. Geometriset rajoitukset

    Kinemaattinen malli luodaan antamalla geometrisiä rajoituksia, jotka määräävät kuinka eri linkit voivat sijaita avaruudessa toisiinsa nähden. Erilaisia liitoksia kuten pallonivel saadaan määriteltyä antamalla geometrisia rajoituksia kahden eri linkin välille. Rajoituksella voi olla myös parametri, esimerkiksi kulman suuruus tai etäisyys, jonka arvo voi vaihdella. Tällöin rajoitusta kutsutaan dynaamiseksi.

    Jos rajoituksia ei ole tarpeeksi, systeemi on alirajoitettu ja sillä on äärettömän monta ratkaisua. Ratkaisijan voi tällöin esittää jonkun mahdollisista ratkaisuista. Jos jokin rajoitus voidaan poistaa ilman, että systeemi muuttuu alirajoitetuksi, on systeemi on ylirajoitettu, Ylirajoitetussa systeemissä on usein ristiriita, jonka takia sitä ei voida ratkaista. Mikäli ristiriitaa ei ole, riippuu ratkaisijan tyypistä löydetäänkö ratkaisu.

    Geometristen rajoitusten ratkaisija antaa kappaleiden sijainnit ja asennot niiden välisten rajoitusten perusteella käyttäen jotain rajoitusten ratkaisualgoritmia. Ratkaisija ratkaisee staattisen tilanteen, jossa dynaamisille rajoituksille on annettu jotkin vakioarvot. Kinemaattinen simulaatio saadaan ratkaisemalla peräkkäisiä staattisia tilanteita.


    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |

    1.3. Käytetty ratkaisualgoritmi

    Kinesimu-ohjelmisto käyttää Glenn Kramerin kehittämää vapausasteiden analysointiin perustuvaa algoritmia, joka on verrattain uusi ja lupaava ratkaisumenetelmä. Kinesimu-ohjelmiston toteuttamisen eräänä keskeisenä tavoitteena on juuri tämän algoritmin toteuttamisen tutkiminen käytännössä.

    1.3.1. Algoritmin toiminta

    Kukin linkki sisältää yhden tai useampia markkereita, jotka ovat oman koordinaatiston omaavia pisteitä. Jokainen rajoitus on relaatio kahden markkerin välillä. Rajoitus voi esimerkiksi määrätä, että markkerien on sijaittava samassa pisteessä tai että niiden tietyt koordinaattiakselit ovat saman suuntaisia.

    Rajoitusten määräämisen lisäksi vähintään yhden markkerin täytyy olla kiinnitetty globaaliin koordinaatistoon, jotta voitaisiin ratkaista linkkien keskinäisen sijainnin lisäksi myös niiden sijainti globaalissa koordinaatistossa. Kaikki markkerit on siis saatava kiinnitettyä. Tilanteen mukaan saatetaan tarvita lukuisiakin kiinnitettyjä markkereita ennenkuin systeemi saadaan ratkaistua.

    Menetelmä perustuu geometriseen järkeilyyn. Se on lähinnä symbolinen menetelmä, jossa rajoitusten ratkaisu tapahtuu siirtämällä ja pyörittämällä geomeja eli linkkejä. Rajoitusten ratkaisu tapahtuu siten, että kaikki aikaisemmin täytetyt rajoitukset pysyvät voimassa siihen asti, kunnes joko kaikki rajoitukset on täytetty tai huomataan ettei kaikkia rajoituksia voi yhtäaikaa täyttää. Tämän takia kunkin rajoituksen täyttämisen jälkeen siirretyn geomin vapausasteita on vähennettävä siten, että täytettyä rajoitusta ei enää ko. geomia siirtämällä ja pyörittämällä voida rikkoa.

    Jäljelle jääville vapausasteille joudutaan määrittämään lokukset . Esimerkiksi rajoittamattomalla markerilla on tasossa kaksi siirtovapausastetta ja yksi pyöritysvapausaste. Jos markerille täytetään rajoitus, jonka mukaan sen täytyy olla tietyllä etäisyydellä jonkin kiinnitetyn markerin koordinaatiston määräämästä suorasta, voi se liikkua enää suoran suuntaisesti. Nyt markerilla on jäljellä yksi siirtovapausaste ja yksi pyöritysvapausaste. Siirtovapausasteeseen liittyvä lokus on se suora, jonka suuntaisesti piste voi liikkua.

    Rajoituksen täyttäminen kahden markerin välillä edellyttää, että toinen niistä on riittävästi rajoitettu, jotta sen myöhempi siirtely ei riko täytettyä rajoitusta. Toisella markerilla pitää vastaavasti olla riittävästi vapausasteita, jotta sitä siirtämällä ja pyörittämällä saadaan rajoitus täytettyä. Edellä mainitussa esimerkissä siirrettävällä markerilla täytyy olla vähintään yksi siirtovapausaste. Lisäksi jos markerilla on vain yksi siirtovapausaste, siihen liittyvä lokussuora ei saa olla samansuuntainen kohdesuoran kanssa.

    Kutakin geomia varten on laadittu reseptikirja, jossa kerrotaan millaisilla siirroilla ja pyörityksillä kunkintyyppinen rajoitus saadaan toteutettua, kun geomilla on tietyt vapausasteet. Jos esimerkiksi kahden markerin tulee olla samassa paikassa, siirretään toinen markkeri samaan paikkaan toisen kanssa. Jos pisteellä on kaksi siirtovapausastetta, voidaan siirto toteuttaa aina. Jos sillä on vain yksi siirtovapausaste, onnistuu siirto vain lokussuoran kulkiessa kohdepisteen kautta.

    Välillä joudutaan täyttämään rajoituksia silloinkin, kun kumpikaan geomeista ei ole riittävästi rajoitettu. Tähän joudutaan esimerkiksi silloin, kun kahden tietynpituisen janan toiset päätepisteet on kiinnitetty ja tulisi täyttää rajoitus, jonka mukaan vapaiden päätemarkkerien tulisi yhtyä. Tiedetään, että kumpikin vapaa markkeri voi liikkua ympyrän kehällä, jonka säde on ko. janan pituus. Siispä päätepisteet voivat yhtyä näiden ympyrälokusten leikkauspisteissä. Valitaan leikkauspiste, josta tehdään väliaikainen markkeri. Tämän jälkeen kumpikin päätemarkkeri pyöräytetään yksi kerrallaan valittuun leikkauspisteeseen täyttämällä yhtenevyysrajoitukset väliaikaisen markkerin ja päätemarkkerien välillä.

    Leikkauspisteiden laskemiseksi kehitetään omat metodinsa kullekin geomiparille ottaen huomioon kummankin geomin vapausasteet. Tämä menettely tietysti toimii parhaiten silloin, kun saadaan äärellinen määrä leikkauspisteitä. Jos leikkauksena saadaan jokin aliavaruus, geomien vapausasteet vähenevät, mutta rajoitusta ei voida vielä ratkaista. Ei tietenkään ole mitään hyötyä esimerkiksi kahden vapaasti liikkuvan pisteen mahdollisten sijaintien leikkauksesta, joka on koko taso.

    Aina ei ongelmaa voida ratkaista pelkästään lähtemällä liikkeelle kiinnitetyistä markkereista ja kiinnittämällä muut yksi kerrallaan. Usein ongelma joudutaan ratkaisemaan rekursiivisesti. Ensin etsitään kaikki sellaiset rajoitukset, jotka kiinnittävät kaksi markkeria ja samalla geomia toistensa suhteen, ei siis vielä globaalin koordinaatiston suhteen. Tällaisista geomipareista muodostetaan makrogeomeja, eli ne yhdistetään. Esimerkiksi jos kahden markkerin välillä on yhtenevyys- ja kulmarajoitukset, ovat ne kiinnitetyt toistensa suhteen, mutta eivät globaalin koordinaatiston suhteen. Tällaisia toistensa suhteen kiinnitettyjen markkerien joukkoja kutsutaan jäykiksi ketjuiksi. Seuraavaksi etsitään rajoitusten muodostamat silmukat. Näistä valitaan ratkaistavaksi sellainen silmukka, jonka osat saadaan toistensa suhteen kiinnitettyä. Silmukka ratkaistaan ja korvataan makrogeomilla. Kysymyksessä ovat jäykät silmukat. Koko prosessia toistetaan, kunnes ongelma on ratkaistu.

    Käytetty menetelmä ei häiriinny turhista rajoituksista, alirajoitetuissa ongelmissa voidaan esittää jokin ratkaisu. Kuvassa 1 on esitetty esimerkki algoritmin toiminnasta.

    Kuva 1. Yksinkertainen esimerkki , joka ratkeaa ilman makrogeomeita.


    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |

    1.4. Ohjelmiston rajoitukset

    Ohjelmisto tukee sopivasti muodostettua joukkoa geometrisia rajoituksia, joilla voidaan määrittää yleisimmät mekaanisissa laitteissa esiintyvät liitokset.

    Mallin fyysistä realistisuutta ei oteta huomioon. Järkevien rajoitusten määrittely on käyttäjän vastuulla. Linkkien välisiä törmäyksiä ei siis huomioida vaan kappaleet ovat haamuobjekteja, jotka voivat kulkea toistensa läpi.


    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |

    2. Järjestelmän ulkoinen kuvaus

    2.1. Yleistä

    Järjestelmän osat ovat: Visualisoija ja instantioija ovat molemmat oma ohjelmansa ja ne kommunikoivat viestien välityksellä. Konvertteri on täysin erillinen oma ohjelmansa, jolla ACIS-mallit voidaan konvertoidaan ennen varsinaisen järjestelmän käynnistämistä.
    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |

    2.2. Tiedostot

    Kaikki ohjelmiston tiedostot ovat hakemiston kinesimu/ alla:
    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |

    2.3. Asennus

    1. Mene hakemistoon kinesimu/source/ ja anna komento 'gmake all'. Tämä luo ohjelmiston binäärit kinesimu/bin/ hakemistoon.

    2. Aseta ympäristömuuttujat $KINEPOLY ja $KINEMODEL osoittamaan hakemistoon, josta mekanismeja ja polygonitiedostoja oletusarvoisesti ladataan.
    Jos ympäristömuuttujille ei anneta arvoa, on oletushakemistona current dir.


    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |

    2.4. Syötetiedostot

    Järjetelmä lukee syötteenä määrittelykielellä tehtyjä tiedostoja ja visuaalisia malleja sisältäviä polygonitiedostoja.

    2.4.1. Polygonitiedosto

    Polygonitiedostot luodaan konvertterin avulla ACIS-malleista, mutta yksinkertaisia malleja voi luoda kirjoittamalla suoraan oman polygonitiedoston.

    Kuhunkin polygonitiedostoon talletetaan yksi visuaalisen malli, joka koostuu useista polygoneista.

    Polygonitiedosto on tekstimuotoinen. Siinä polygonit on lueteltu peräkkäin siten, että yhden polygonin kaikki informaatio on määritelty ennen seuraavaa polygonia.

    Polygonissa on ensimmäisenä kokonaisluku polygonin nurkkapisteiden lukumäärästä. Tämän perässä on lueteltu edellämainittu lukumäärä nurkkapisteitä. Jokainen nurkkapiste koostuu kuudesta floating point luvusta. Nämä ovat nurkkapisteen x, y, ja z-koordinaatit, sekä nurkkapisteeseen liittyvän pinnan normaalivektorin x, y, ja z-komponentit.

    Polygonin nurkkapisteet on lueteltu kappaleen ulkopintaan nähden vastapäiväisessä järjestyksessä. Luvut on erotettu toisistaan 'white space'-merkeillä (= välilyönti, rivinvaihto, tabulaattori).

    Polygonitiedoston rakenne:

    <Int:Poly1_Number_of_points>\n
    <Float:Poly1_Point1_x> <Float:Poly1_Point1_y> <Float:Poly1_Point1_z>
    <Float:Poly1_Norm1_x> <Float:Poly1_Norm1_y> <Float:Poly1_Norm1_z>\n
    <Float:Poly1_Point2_x> <Float:Poly1_Point2_y> <Float:Poly1_Point2_z>
    <Float:Poly1_Norm1_x> <Float:Poly1_Norm1_y> <Float:Poly1_Norm1_z>\n
    ...
    <Int:Poly2_Number_of_points>\n
    <Float:Poly2_Point1_x> <Float:Poly2_Point1_y> <Float:Poly2_Point1_z>
    <Float:Poly2_Norm1_x> <Float:Poly2_Norm1_y> <Float:Poly2_Norm1_z>\n
    <Float:Poly2_Point2_x> <Float:Poly2_Point2_y> <Float:Poly2_Point2_z>
    <Float:Poly2_Norm2_x> <Float:Poly2_Norm2_y> <Float:Poly2_Norm2_z>\n
    ...
    ...
    <EOF>
    


    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |

    3. Järjestelmän sisäinen kuvaus

    3.1. Osajärjestelmäjako

    Järjestelmä koostuu seuraavista osajärjestelmistä:

    Ajettaessa järjestelmä käynnistää kaksi prosessia, joilla molemmilla on oma ikkunansa.

    Prosessi 1 koostuu kääntäjästä, ratkaisijasta ja visualisoijasta.
    Prosessi 2 on instantioija.
    Prosessit kommunikoivat keskenään viestejä lähettämällä.


    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |

    3.2. Osajärjestelmien liitynnät

    Kuva 1. Tason 1 tietovirtakaavio (kuva postscript muodossa).

    3.2.1. Visualisoija<->Instantioija

    Visualisoija kommunikoi instantioijan kanssa viestien välityksellä. Visualisoijan ja instantioijan tilakaavioista selviää, milloin mitäkin viestejä käytetään.

    Instantioijalta tulevat viestit voivat olla seuraavia:

    Visualisoija lähettää instantioijalle seuraavia viestejä:

    3.2.2. Visualisoija<->Kääntäjä

    Visualisoija kutsuu kääntäjää, kun käyttäjä haluaa ladata uuden kinemaattisen mallin. Visualisoija antaa kääntäjälle käyttäjän antaman tiedostonimen ja saa takaisin ilmoituksen kääntämisen onnistumisesta tai epäonnistumisesta sekä linkFiles tietorakenteen, jossa on lueteltu kuhunkin linkkiin liittyvä polygonitiedosto, joka sisältää linkin visuaalisen mallin .

    3.2.3. Visualisoija<->Ratkaisija

    Visualisoija kutsuu ratkaisijaa kolmessa eri tarkoituksessa:

    3.2.4. Kääntäjä<->Ratkaisija

    Kääntäjä kutsuu kinemaattisen mallin konstruktoreja, ja tuloksena syntyy kinemaattisen mallin tietorakenne. Kinemaattisen mallin tietorakenteeseen on kolme globaalia pointteria, jotka ovat sekä kääntäjän että ratkaisijan käytettävissä.

    3.2.5. Kääntäjä<->Instantioija

    Kääntäjä lähettää instantioijalle viestin DYN_PARAMS, kun määrittelytiedosto on saatu käännetyksi. Viesti sisältää listan käyttäjän muuteltavissa olevista dynaamisista rajoituksista tai on tyhjä jos käännös ei onnistunut.

    3.2.6. Ratkaisija<->Instantioija

    Instantioijalta ratkaisijalle tulevat viestit voivat olla seuraavia:

    Ratkaisija lähettää instantioijalle seuraavia viestejä:

    3.2.7. Järjestelmän ulkopuoliset osat

    Käyttäjä kommunikoi instantioijan kanssa antamalla START-, STOP-, LOAD-, QUIT-komentoja sekä dynaamisten rajoitusten alkuarvoja ja muutosfunktioita.

    Käyttäjä kommunikoi visualisoijan kanssa pyörittämällä ja zoomaamalla mallia hiirellä sekä valitsemalla popup-menusta toimintoja.

    Kääntäjä lukee määrittelykieltä sisältäviä tiedostoja.

    Visualisoija lukee polygonimalleja sisältäviä tiedostoja. .

    Virhetilanteissa kaikki osajärjestelmät lähettävät virheilmoitukset instantioijalle, joka näyttää ne käyttäjälle.


    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |

    3.3. Osajärjestelmien tarjoamat palvelut

    3.3.1. Instantioija

    Instantioija on kokonaan oma prosessinsa, joka kommunikoi toisen prosessin kanssa viestien välityksellä. f Instantioija ymmärtää seuraavat viestit:

    3.3.2. Visualisoija

    Visualisoija huolehtii kaikista piirtämiseen liittyvistä tehtävistä. Lisäksi se hoitaa prosessin 1 kommunikoinnin käyttäjän ja instantioijan kanssa.

    Piirtäminen: Visualisoija tarjoaa seuraavat funktiot renderöintiä varten. Funktiot on dokumentoitu renderer modulin kuvauksessa.

    void vi_clear_window();
    void vi_flush_window();
    void vi_render(kinLink *links, int num_links);
    void vi_redraw();
    void vi_plot_mark(int x, int y, int z, char *label);
    
    Kommunikointi:

    Visualisoija ymmärtää seuraavat instantioijalta tulevat viestit:

    3.3.3. Kääntäjä

    Kääntäjä tarjoaa funktion:

    bool co_compile(char* filename, linkFiles **linkfiles);

    co_compile():lle annetaan määrittelykielellä luodun kinemaattisen mallin sisältävän tiedoston nimi sekä osoitin osoittimeen linkFiles tietorakenteeseen. co_compile() varaa muistin linkfiles tietorakenteelle, täyttää sen ja palauttaa osoittimen siihen linkfiles muuttujassa.

    co_compile() palauttaa TRUE, jos käännös onnistui, muutoin FALSE.

    co_compile():n osajärjestelmän ulkopuolelle näkyvänä tehtävänä on:

    3.3.4. Ratkaisija

    Ratkaisija tarjoaa funktiot:

    void so_init()
    void so_last()
    int so_solve(kinLink* kinLinks)
    

    so_init() lukee viestin PARAMS_FUNCS, jossa on instantioijan lähettämät dynaamisten rajoitusten alkuarvot ja muutosfunktiot.

    so_last() lähettää instantioijalle viestin LAST_VALUES, joka sisältää viimeisen ratkaisun dynaamisten rajoitusten arvot.

    so_solve():n osajärjestelmän ulkopuolelle näkyvänä tehtävänä on:

    3.3.5. Visuaalisen mallin määrittelijä

    Visuaalisen mallin määrittely tapahtuu joko lukemalla ennaltarakennettu malli ACIS-formaatin tiedostosta tai määrittelemällä malli ACIS:in API käskyillä. Mallin määrittelijän tehtävä on luoda jommallakummalla tavalla ACIS-mallin tietorakenne ja kutsua polygonisoijaa.

    Käyttäjä voi laatia oman visuaalisen mallin määrittelyohjelman.

    3.3.6. Polygonisoija

    Polygonisoija tarjoaa funktiot:
    int polyg_init (float surf_dev, float norm_dev);
    int polyg_attr (float surf_dev, float norm_dev);
    int polyg_save (char *filename, BODY* body);
    int polyg_terminate ();
    
    Polygonisoija muodostaa polygonitiedoston. Virhetilanteessa polygonisoija palauttaa ERROR.


    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |

    3.4 Tilakaaviot

    Notaatio: Laatikot kuvaavat tiloja, nuolet mahdollisia tilasiirtymiä ja paksut vaakaviivat tapahtuma-toiminto pareja siten, että tapahtuma on viivan yläpuolella ja toiminto alapuolella.

    3.4.1. Prosessin 1 tilakaavio.

    Kuva 2. Prosessin 1 tilakaavio (kuva postscript muodossa).

    Tapahtumat ja niiden seurauksena tapahtuvat toiminnot.

    3.4.2. Prosessin 2 (instantioija) tilakaavio.

    Kuva 3. Prosessin 2 tilakaavio (kuva postscript muodossa).

    Tapahtumat ja niiden seurauksena tapahtuvat toiminnot.


    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |

    3.5. Keskeisimmät tietorakenteet

    linkFiles

    Kääntäjän co_compile() palauttaa visualisoijalle tietorakenteen linkFiles.
    typedef struct { 
      int numLinks;               /* total number of links */
      int numvisModels;           /* total number of visualModels */
      struct visualModel *models; /* pointer to a table which includes
                                     all visual models */
    } linkFiles;
    

    visualModel

    typedef struct { 
      int id;                 /* id of link (0 = common object) */
      float red, green, blue; /* color of link */
      char *filename;         /* polygon filename */
    } visualModel;
    
    

    kinLink

    KinLink on tietorakenne joka annetaan renderöijälle, kun uusi malli halutaan piirtää.
    typedef struct {
      int id;           /* id of link, 0 = common object */
      double x,y,z;     /* position */
      double axis1_x, axis1_y, axis1_z;
      double axis2_x, axis2_y, axis2_z;
      double angle1;
      double angle2;
      double len;       /* lenght of common object with 2 points */
    } kinLink;
    

    Kinemaattinen malli

    Kinemaattinen malli on C++-luokista muodostuva tietorakenne. Tässä esitetään kustakin luokasta ne muuttujat, jotka ovat sekä kääntäjän että ratkaisijan käytössä.

    class Geom {
      char            *name;
      Deque           *markers;
      Position        *init_pos;       // initial global position
      int              visual_object;  // id number,  0 = common object
    };
    
    class Constraint {
      char            *name;
      Marker          *marker1;
      Marker          *marker2;
      constraint_type  type;          // enum: inline-z, parallel-z ...
      float            param;
    };
    
    class Marker {
      char            *name;
      Link            *parent_geom;
      Position        *init_global_pos;  // initial global position
      Position        *init_local_pos;   // initial local position
      Position        *init_pos;         // local or global position
    };
    
    class Position {
      position_type    co_state;          // enum: FIXED, FREE
      Point            pos;
      Vector           ang_x;
      Vector           ang_y;
      Vector           ang_z;
    };
    
    class Point {
      double           x;
      double           y;
      double           z;
    };
    
    class Vector {
      double           x;
      double           y;
      double           z;
    };
    

    Järjestelmässä on kolme globaalia pointteria kinemaattisen mallin listoihin:

    List *km_geom_list;        // kaikki geomit sisältävä lista.
    List *km_constr_list;      // kaikki rajoitukset sisältävä lista.
    List *km_dyn_constr_list;  // kaikki dynaamiset rajoitukset sisältävä lista
    

    Markkerit ovat linkkeihin kuuluvissa markkerilistoissa.


    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |

    3.6. Toteutuksen modulirakenne

    3.6.1. Instantioija

    Instantioijan tehtävänä on simulaattorin ohjaaminen.
    Kuva instantioijan modulikaaviosta (postscript).


    Tiedostot:

    Moduli: init

    Tehtävä:

    Instantioijan C-ohjelman ja Tcl/Tk-ikkunan käynnistys.

    Rajapinta:

    Komentoriviltä käynnistettävä oma prosessinsa.
    Komento "ins" käynnistää C-ohjelman inst.c, joka evaluoi ensimmäisenä argumenttinaan olevan tcl-tiedoston ins1.
    main(int argc, char** argv);

    Kutsuu moduleita:

    Toiminta:

    Evaluoidaan tcl-skripti ja tehdään alustukset ennen siirtymistä tapahtumasilmukkaan. Kutsuu modulia mainLoop, joka ryhtyy tutkimaan käyttäjän antamia tapahtumia ja tulevia viestejä.

    Virhe- ja poikkeustilanteet:

    Jos ikkunaa ei saada, lopetetaan instantioija.

    Testattavuus:

    Testaaminen voidaan tehdä itsenäisesti ilman testiajuria, kunhan X-ikkunointi toimii.


    Moduli: TclParser

    Tehtävä:

    Toteuttaa ajon aikaiset Tcl-komennot Wish-ikkunassa.

    Rajapinta:

    Tk:n tapahtumat yhdistetty bind-komennolla Tcl-skripteihin.

    Kutsuu kirjastomodulia Wish, joka näyttää tulokset ikkunassa.

    Virhe- ja poikkeustilanteet:

    Tcl:n parseri ilmoittaa virheistä.

    Testattavuus:

    Ei testaamista, kyseessä on valmis moduli.


    Moduli: mainLoop

    Tehtävä:

    Tämä C-ohjelman inst.c silmukka toteuttaa simulaattorin muiden osajärjestelmien lähettämät viestit. Valitsee viestiä vastaavan Tcl-käskyn ja täten ohjaa instantioijaa.

    Rajapinta:

    C-ohjelma inst.c käskee TclParseria komennolla Tcl_Eval. Tk:n widgetit käyttävät ohjelman valvomaa viestien välitystä.

    Kutsuu moduleita:

    Virhe- ja poikkeustilanteet:

    Virhetilanteissa tulostetaan virheilmoitus instantioijan Messages-ikkunaan. Erityisesti valvotaan tilakoneen tilasiirtymien mukaista viestiliikennettä, eli estetään käyttäjän virheelisten toimintojen viestitys.

    Testattavuus:

    Modulin testaus tehdään testiajurin kanssa, joka matkii prosessia yksi. Testauksessa katetaan tilakaavion kaikki viestit. Varmistetaan tilakaavion mukainen toiminta.


    Moduli: TkWidgets

    Tehtävä:

    Toteuttaa napit "Start", "Stop" sekä alasvetovalikon kohdan "Quit". Toteuttaa siis valmiit Tk-widgetit, kuten buttonit ja menut.

    Rajapinta:

    Komennoilla "button" ja "menuselection" tehdyt osat Tcl-skriptistä.

    Toiminta:

    Käyttäjän painaessa nappia tai valitessa valikosta "Quit":n, antaa tapahtuman mainLoopille sekä lähettää visualisoijalle oikean viestin.

    Kutsuu kirjaston kineMessage funktiota kineSend viestien lähettämiseen ja funktiota kineReceive viestien vastaanottamiseen.

    Virhe- ja poikkeustilanteet:

    Tk:n kirjaston antaman virhetilanteiden käsittelyn lisäksi huomioitava käyttäjän tekemä virheellinen toimintayritys.

    Testattavuus:

    Testauksessa varmistetaan, että oikea viesti lähtee oikealla tapahtumalla. Tähän tarvitaan testiajuria visdriver.c.


    Moduli: showParams

    Tehtävä:

    Ottaa vastaan käyttäjän antamat dynaamisten rajoitusten arvot sekä tulostaa algoritmin käyttämiä arvoja.

    Rajapinta:

    Kaikki parametrilistan käsittelyä hoitavat Tcl-skriptit.

    Käyttää kirjastomodulia kineMessage kommunikointiin ratkaisijan kanssa.

    Toiminta:

    Kun ratkaisijalta tulee viesti last_values, näyttää parametrilistan. Ottaa vastaan parametrin asetusarvon käyttäjän valitessa parametrilistasta muutettavan parametrin. Arvot syötetään näppäimistöltä.

    Parametrilista vierii käyttäjän liikuttaessa scrollBar:ta.

    Kun ratkaisijalta tulee viesti last_values, näyttää viestissä tulevat parametrien nimet ja arvot parametrilistassa.

    Ottaa vastaan käyttäjän valitseman syöttöfunktion käyttäjän valitessa "Funcs"-valikosta kohdan.

    Ylläpitää valinnoista viestioliota, joka on valmiina lähetettäväksi ratkaisijalle kutsumalla funktiota kineSend.

    Virhe- ja poikkeustilanteet:

    Huomioitava käyttäjän virheelinen toimintayritys, josta annetaan ilmoitus ja äänimerkki.

    Testattavuus:

    Testauksessa varmistetaan, että oikea viesti muodostetaan käyttäjän antaessa asetusarvon. Testiajuria tarvitaan näyttämään parametrien uudet arvot.


    Moduli: fileBrowser

    Tehtävä:

    Antaa käyttöliittymän ladattavan tiedoston valitsemiseen.

    Rajapinta:

    mainLoop kutsuu modulia, kun käyttäjä valitsee "File"-valikosta "Load":n.

    Toiminta:

    Kun käyttäjä on valinnut ladattavan tiedoston, kutsuu kirjastofunktiota kineSend valitun tiedoston välittämiseksi visualisoijalle.

    Ottaa vastaan ilmoituksen latauksen onnistumisesta visualisoijalta kutsumalla kirjastofunktiota kineReceive.

    Käyttää Unixin komentoa "ls" tiedostojen nimeämiseen.

    Virhe- ja poikkeustilanteet:

    Virheelisen toimintayrityksen lisäksi virhe voi tulla käyttöjärjestelmältä. Molemmissa tapauksissa toiminto lopetetaan ja tulostetaan virheilmoitus Messages-ikkunaan.

    Testattavuus:

    Testauksessa tarvitaan testiajuria todentamaan oikean tiedostonimen lähetys.

    Moduli: Messages

    Tehtävä:

    Tarjoaa ikkunan virheilmoitusten näyttämiseen, sekä toimii leikkauspisteiden valintatilanteessa valinnan näyttäjänä.

    Rajapinta:

    mainLoop kutsuu modulia saatuaan viestin CHOOSE tai viestin TEXT.

    Toiminta:

    Tulostaa viestissä TEXT olevan tekstin omalle rivilleen.

    Tarjoaa vierityspalkin rivien selailemiseen.

    Valintatilanteessa tyhjentää ikkunan, näyttää valintatekstin sekä viestissä CHOOSE olevat koordinaattipisteet. Käyttäjän napauttaessa pisteen riviä lähettää viestissä CHOSEN valinnan ratkaisijalle ja tyhjentää ikkunan.

    Käyttää modulin kineMessage funktiota kineReceive virheilmoitusten ja valintapisteiden saamiseen sekä funktiota kineSend valinnan ilmoittamiseen.

    Virhe- ja poikkeustilanteet:

    Toiminta ei saa poiketa tilakaaviosta. Viestien epäonnistuminen saattaa pysäyttää simulaation.

    Testattavuus:

    Testataan testiajurin kanssa tekstirivin ja valintatekstin tulostuminen sekä oikean viestin lähteminen valinnan yhteydessä.


    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |

    3.6.2. Visualisoija

    Kuva visualisoijan modulikaaviosta (postscript).


    Moduli: InitGL

    Tehtävä:

    Käynnistää järjestelmän ja alustaa OpenGL:n ja GLUT:n tilan.

    Tiedostot:

    Rajapinta:

    void main(int argc, char** argv);

    Kutsuu moduleita:

    Toiminta:

    Alustaa viestien välityksen prosessien välillä.

    Kutsuu GLUT:n funtioita, joilla alustetaan:

    Kutsuu OpenGL:n funtioita, joilla alustetaan:

    Algoritmit:

    Tietorakenteet:

    Virhe- ja poikkeustilanteet:

    GLUT:n glutInit():ä kutsuttaessa poistutaan järjestelmästä, jos GLUT:ia ei saatu alustettua.

    Testattavuus:

    Modulin toteutus on suoraviivainen ja toiminta voidaan todeta, jos visualisoijan ikkuna aukeaa, popup-menu ilmestyy oikeanpuolimmaisesta hiiren napista ja hiirellä pystyy antamaan kaikki halutut toiminnot. OpenGL:n alustus on onnistunut, jos kappaleiden valaistus toimii (näyttää oikealta).


    Moduli: Callbacks

    Tehtävä:

    Ottaa vastaan instantioijalta tulevat viestit ja GLUT:n kautta tulevat tapahtumat ja joko käsittelee ne joko itse tai kutsuu muita moduleita tarpeen tullen.

    Tiedostot:

    Rajapinta:

    Modulia kutsuu vain GLUT kirjasto, jolle on annettu sitä alustettaessa osoittimet seuraaviin funktioihin.

    extern void vi_display(void);
    extern void vi_reshape(int width, int height);
    extern void vi_mouse(int button, int state, int x, int y);
    extern void vi_mousemotion(int x, int y);
    extern void vi_visibility(int state);
    extern void vi_menu(int);
    extern void vi_submenu1(int);
    extern void vi_idle(void);
    

    Kutsuu moduleita:

    Toiminta:

    Algoritmit:

    Tietorakenteet:

    Virhe- ja poikkeustilanteet:

    Testattavuus:

    On varmistettava, että jokaista Callback-funktioita kutsutaan silloin kuin pitäisi. Tämän voi tehdä lisäämällä tulostuskomennon jokaiseen funktioon ja testaamalla ohjelmaa antamalla hiirellä erilaisia tapahtumia (ikkunoiden siirto, ikkunoiden koon muuttaminen, popup menujen käyttö, mallin pyöritys ja zoomaus).

    Testauksessa on kiinnitettävä huomiota prosessien välisen kommunikoinnin onnistumiseen. On testattava kaikkien käytettyjen viestien lähetys ja vastaanotto ja varmistuttava siitä että kontrolli kulkee tilakaaviossa kuvatulla tavalla.


    Moduli: MakeDlists

    Tehtävä:

    Tekee OpenGL:n display-listan kustakin käyttäjän määrittelemästä linkistä, "common objectista" sekä koordinaattiakseleista.

    Tiedostot:

    Rajapinta:

    LinkInfo* vi_makeDlists(linkFiles *links);
    

    Kutsuu moduleita:

    Toiminta:

    Lukee linkkeihin liittyvät visuaaliset mallit tiedostoista, jotka annetaan linkFiles tietorakenteessa ja muodostaa display-listan jokaisen linkin visuaalisesta mallista. Muodostaa tietueen LinkInfo ja palauttaa sen. Jos tiedostoa ei saada luettua tai se ei ole oikeassa formaatissa palautetaan NULL. Lisäksi muodostetaan display-lista common objectista ja koordinaattiakseleista.

    Algoritmit:

    Tietorakenteet:

    Modulissa alustetaan LinkInfo tyyppinen tietorakenne, joka sisältää tarvitavat tiedot kinemaattisen mallin linkkeihin liittyvistä visuaalisista malleista.

    OpenGL:ltä saadaan haluttu määrä vapaita, peräkkäisiä display-listojen numeroita alkaen luvusta, jota kuvataan base:lla. Käytetyt display-listojen numerot ovat siis base+0, base+1 ... Num_links sisältää mallin linkkien kokonaismäärän ja num_dlists malliin liittyvien visuallisten mallien kokonaismäärän.

    typedef struct { 
      int num_links;     /* total number of links */
      int num_dlists;    /* size of table */
      int base;          /* number of first displaylist */
      int *ids;          /* pointer to id table */
    } LinkInfo;
    
    

    Virhe- ja poikkeustilanteet:

    Jos joku annetuista tiedostoista ei löydy tai se ei ole oikean formaatin mukainen, palautetaan kutsujalle virhearvona NULL ja tulostetaan käyttäjälle ilmoitus tapahtuneesta virheestä ja siitä minkä tiedoston käsittelyssä se tapahtui.

    Testattavuus:

    On tehtävä oikeassa formaatissa oleva testitiedosto, joka voidaan antaa syötteenä modulille. Onnistunut tulos voidaan todeta visualisoimalla malli käyttäen renderer modulia. Lisäksi modulia voi testata virheellisillä syötteillä, jotka sen on hylättävä.


    Moduli: Renderer

    Tehtävä:

    Hoitaa kaiken visualisoijan ikkunaan tapahtuvan piirtämisen.

    Tiedostot:

    Rajapinta:

    extern void vi_clear_window();
    extern void vi_flush_window();
    extern void vi_draw_welcome();
    extern void vi_render(kinLink *links, int num_links);
    extern void vi_redraw();
    extern void vi_plot_mark(int x, int y, int z, char *label);
    
    

    Kutsuu moduleita:

    Toiminta:

    extern void vi_clear_window();

    vi_clear_window()

    Tyhjää ikkunan kuva- ja syvyyspuskurit.

    vi_flush_window()

    Lopettaa kuvan piirtämisen ja laittaa muutokset näkyviin. Kutsumalla glutSwapBuffers():a, joka vaihtaa kaksoispuskuroinnin näkyvää puskuria.

    vi_render()

    Kutsuu viewingTransform():a, joka asettaa kameran oikaan paikkaan ja asentoon. Pyörittää ja siirtää kunkin linkin sen oikeaan sijaintiin globaalissa koordinaatistossa. Yhdistää linkkiin id:n perusteella oikean display-listan ja piirtää sen ikkunaan. Muodostaa mallista display-listan, jota voidaan käyttää nopeuttamaan uudelleen piirtämistä.

    vi_redraw()

    Kutsuu viewingTransform():a, joka asettaa kameran oikaan paikkaan ja asentoon. Piirtää uudelleen viimeisen vi_render():n tekemän display-listan.

    Algoritmit:

    Käyttää LinkInfo tietorakennetta. Ids taulukosta saadaan tiettyyn id:hen liittyvä display-listan numero laskemalla yhteen base ja taulukon indeksi, josta kyseinen id löytyi.

    Tietorakenteet:

    Virhe- ja poikkeustilanteet:

    Jos tietylle id:lle ei löydy vastaavaa display-listaa on kääntäjä tehnyt virheen.

    Testattavuus:

    Toiminta voidaan todeta visualisoimalla erilaisia valmiita malleja. Luomalla linkkien asennot sisältävä tietorakenne käsin ja muuttamalla sen arvoja itse ilman ratkaisijaa, voidaan testaus suorittaa ratkaisijasta riippumatta.


    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |

    3.6.3. Kääntäjä

    Kuva kääntäjän modulikaaviosta (postscript).


    Moduli: InitCompiler

    Tehtävä:

    Määrittelykielen kääntäjän pääohjelma.

    Tiedostot:

    Rajapinta:

    int co_compile(char *filename, struct linkFiles **linkfiles);
    

    Kutsuu moduleita:

    Toiminta:

    Avaa määrittelykielen tiedoston ja kutsuu parseria. Kutsuu lopuksi tietorakenteen tarkistajaa.

    Tietorakenteet:

    Osajärjestelmän sisällä käytettävät tietorakenteet

    Virhe- ja poikkeustilanteet

    Mikäli kääntämisvaiheessa on esiintynyt virhe, co_compile() antaa paluuarvona FALSE.


    Moduli: Parser

    Tehtävä:

    Jäsentää määrittelykielen koodin.

    Tiedostot:

    Rajapinta:

    void co_parse (FILE *fp);
    

    Kutsuu moduleita:

    Toiminta:

    Jäsentäjä tehdään Bison:lla, joka on yacc:in c++-versio. Jäsentäjä lukee tokenstreamia ja kutsuu kinemaattisen mallin määrittelyfunktioita.

    Linkin sisällä määritellyt markerit konstruktoidaan, ja laitetaan listaan. Lista annetaan parametriksi linkin konstruktorille.

    Koordinaatistomuunnoksen konstruktointi tuottaa paluuarvona pointterin koordinaatistomuunnokseen. Tämä annetaan parametrina linkille tai markerille.

    Linkit ja rajoitukset laitetaan omiin globaaleiden pointterien osoittamiin listoihin. Markerit, jotka eivät kuulu mihinkään linkkiin, laitetaan omaan listaan, jota käytetään vain kääntäjä-osajärjestelmän sisällä. Tämä markerilista tyhjennetään checkModel:issa (markereille luodaan omat linkit).

    Visuaalisen mallin tiedostonimet ja parametrit laitetaan tietorakenteeseen, johon on annettu pointteri kääntäjää kutsuttaessa. Värinmääritykset tallennetaan omaan linkattuun listaan, jota käytetään vain kääntäjä-osajärjestelmän sisällä.

    Vaihtoehtoisten ratkaisujen numero talletetaan globaaliin muuttujaan.

    Virhe- ja poikkeustilanteet

    Jäsentäjä tulostaa käännösvaiheessa esiintyvät virheet yyerror - funktiolla instantioijan messages-ikkunaan. Virheistä ilmoitetaan ainakin rivinumero, jolla virhe esiintyi. Lisäksi laaditaan muutamia virheproduktioita.

    Virheilmoituksen lisäksi annetaan initCompiler:ille paluuarvona FALSE.


    Moduli: Lexer

    Tehtävä:

    Lexeri muodostaa määrittelykielen tiedostosta token-stream:in.

    Tiedostot:

    Rajapinta:

    int yylex (void);
    

    Toiminta:

    Lekseri tehdään flex:illa, joka on lex:in c++-versio. Lekseri muodostaa määrittelykielen tiedostosta token-stream:in.


    Moduli: ConstructModel

    Tehtävä:

    Muodostaa kinemaattisen mallin tietorakenteen.

    Tiedostot:

    Rajapinta:

    void      co_global_marker (char *, Position *);
    Marker   *co_local_marker  (char *, Position *);
    void      co_link          (char *, Position *, int, Deque *);
    void      co_constraint    (char *, constraint_type, bool, char *, char *, double, bool);
    void      co_solution      (int);
    void      co_load          (char *, int, char *);
    void      co_color         (char *, double, double, double);
    Position *co_coord         (double, double, double, double, double, double);
    Position *co_coord_autoz   (double, double, double);
    Position *co_coord_autox   (double, double, double);
    Position *co_coord_ident   ();
    Position *co_coord_undef   ();
    

    Toiminta:

    Muodostettaessa constraint:ia moduli etsii rajoituksessa nimetyt markerit mallin tietorakenteesta ja kutsuu constraint:in konstruktoria.

    Muodostettaessa marker:ia moduli etsii tietorakenteesta samannimistä aiemmin määriteltyä markeria (markeri voidaan määritellä sekä linkin sisällä että yksinään). Mikäli markeria ei ole määritelty aiemmin, kutsutaan marker:in konstruktoria. Lopuksi kutsutaan metodia, jolla markerille annetaan sen globaali sijainti.

    Muodostettaessa link:iä kutsutaan suoraan linkin konstruktoria. Jäsentäjä on laittanut linkkiin kuuluvat markkerit listaan, ja listan pointteri annetaan parametrina konstruktorille.

    Muodostettaessa visuaalisen mallin viittaukselle tietorakennetta, moduli etsii värinmääritys-listasta värinnimen ja siihen liittyvät parametrit.

    Virhe- ja poikkeustilanteet

    constructModel antaa virheilmoituksen instantioijan messages-ikkunaan, jos constraint:issa ilmoitettuja markereita ei ole määritelty tai jos visuaalisen mallin tiedoston määrittelyssä ilmoitettua väriä ei ole määritelty. Lisäksi annetaan virheilmoitus, jos markerille määritellään sen globaali sijainti kahdesti tai se liitetään kahteen linkkiin.


    Moduli: CheckModel

    Tehtävä:

    Lisää oletusarvoista informaatiota kinemaattisen mallin tietorakenteeseen sinne mistä se jäi käyttäjältä määrittelemättä.

    Tiedostot:

    Rajapinta:

    void co_check_model (void);
    

    Toiminta:

    Markereille, jotka eivät ennestään kuulu millekään linkille, luodaan uudet linkit. Kukin uusi linkki sisältää yhden markerin.

    Mikäli johonkin linkkiin kuuluu kaksi markeria ja niiden sisäisten koordinaatistojen suuntavektoreille on määritelty autodirect-z, asetetaan markerien z-akselit keskenään samansuuntaisiksi ja kohtisuoraksi markerien väliseen janaan. Mikäli suuntavektoreille on määritelty autodirect-x, asetetaan markerien x-akselit osoittamaan toisiaan. Autodirect-määritys kiinnittää kaikkien akselien suunnat, jotta markeri tulisi täysin kiinnitetyksi linkin koordinaatistoon.

    Mikäli jokin markeri kiinnittää linkin globaaliin koordinaatistoon, lasketaan linkille koordinaatisto globaalissa koordinaatistossa. Mikäli linkki on kiinnitetty globaaliin koordinaatistoon, lasketaan linkin jokaiselle markkereille niiden koordinaatisto globaalissa koordinaatistossa.

    Moduli laskee visuaalisten mallien lukumäärän. Jos linkkiin kuuluu polygonimalli lasketaan se yhdeksi visuaaliseksi malliksi. Näkymätön linkki lasketaan 0:ksi ja "common-object" n-1:ksi tai n:ksi visuaaliseksi malliksi riippuen "common-object":in tyypistä.

    Moduli lähettää instantioijalle viestin, jossa on lista dynaamisten rajoitusten nimistä.

    Moduli vapauttaa värinmäärityslistan käyttämän muistin.

    Lisäksi moduli asettaa jokaiselle markerille parent-geom -tiedon, sekä yhdistää markerien globaalin ja lokaalin sijainnin tiedon, siten että jäljelle jää vain globaali sijainti.

    Virhe- ja poikkeustilanteet

    Moduli antaa virheilmoituksen standard error:iin, jos linkkiin kuuluville markereille määritellyt koordinaatistomuunnokset ovat ristiriitaisia. Virheilmoitus annetaan myös, jos autodirect-muunnos ei onnistu esim. tapauksessa, jossa autodirect on määritelty vain yhdelle markerille.

    Virheilmoituksen lisäksi annetaan initCompiler:ille paluuarvona FALSE.


    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |

    3.6.4. Ratkaisija

    Kuva ratkaisijan modulikaaviosta (postscript).

    Kaikki alla mainitut algoritmit on perusteellisemmin esitetty Glen Kramerin kirjassa "Solving Geometric Constraint Systems".

    Tämänhetkinen toteutus eroaa joissakin kohdissa toivotusta lopullisesta toteutuksesta, jota tämä dokumentti pyrkii kuvaamaan.


    Moduli: main_loop

    Tehtävä:

    Päätetään, missä järjestyksessä rajoitukset ratkaistaan.

    Tiedostot:

    Rajapinta:

    Modulia kutsutaan visualisoijasta.

    void so_init()
    void so_last()
    bool so_solve(kinLink *links)
    void write_result(kinLink* links)
    

    kinLink on tietorakenne, johon ratkaisija tallettaa tiedot linkkien asennosta, sijainnista, graafisen muodon tunnuksen ja pituuden.
    Pituutta käytetään vain silloin, kun käytetään graafisena muotona common objectia. Common object yhdistää geomin markkerit toisiinsa, eli sitä voi käyttää helppona tapana visualisoida geomi, kun sopivaa graafista mallia ei ACIS:lla ole piirretty tai kannata piirtää. Common object on pelkkä "tanko", joten jos geomi sisältää enemmän kuin kaksi markkeria, siitä luodaan useita common objecteja, joista kukin yhdistää kaksi markkeria toisiinsa.
    Common object on dokumentoitu tarkemmin visualisoijan yhteydessä.
    Pointterit geomien listaan ja rajoitusten listaan ovat globaaleja.

    Kutsuu moduleita:

    Toiminta:

  • So_init ja so_last on dokumentoitu kohdassa 3.3.

  • so_solve:

    Ensimmäiseksi muutetaan dynaamisten rajoitusten arvoja. Seuraavaksi palautetaan kaikki markkerit alkuperäisiin asentoihinsa. Tällä vältetään kasautuvat pyöristysvirheet pitkien animaatioiden aikana. Tämän jälkeen luodaan jokaista geomia kohti yksi makrogeomi, paitsi että pysyvästi globaaliin koordinaatistoon kiinnitetyt geomit kerätään samaan makrogeomiin. Ennen varsinaista ratkaisusilmukkaa käsitellään vielä displacement-rajoitukset. Displacement- rajoitukset korvataan siis jo tässä vaiheessa coincident-rajoituksella. Tämä tapahtuu laskemalla, mihin displacement rajoitus määrää rajoitettavan geomin ja asettamalla saatuun pisteeseen ylimääräinen markkeri. Em. coincident rajoitus pakottaa geomin oikeaan sijaintiinsa ratkaisun aikana.

    Kutsuu modulia find_rigid_chain, joka antaa seuraavan ratkaistavan jäykän geomiparin, mikäli sellainen on löydettävissä. Mikäli kumpikaan geomeista ei ole kiinnitetty, kiinnitetään niistä toinen väliaikaisesti. Parin määrittävät rajoitukset ratkaistaan kutsumalla action_analysis-modulia. Rajoituksia käydään läpi kunnes ne kaikki saadaan ratkaistua, ratkaisujärjestys ei ole täysin vapaa. Lopuksi vapautetaan tarvittaessa väliaikaisesti kiinnitetty geomi.

    Mikäli rajoituksia on vielä jäljellä, etsitään seuraavaksi jäykkä silmukka kutsumalla modulia find_and_choose_loop. Jos silmukkaa ei löydy, on ongelma alirajoitettu. Jos silmukka ei sisällä kiinnitettyä geomia, joudutaan jälleen tekemään väliaikainen kiinnitys. Lisäksi joskus saatetaan joutua kiinnittämään juuri tietty geomi riippumatta siitä, sisälsikä silmukka kiinnitetyn geomin. Tätä ei ole vielä toteutettu. Aina ei myöskään voida algoritmisesti todeta, ratkeaako silmukka, joten tarpeen tullen pitäisi käyttää yritys-erehdys -menetelmää. Tätä ei myöskään ole vielä toteutettu. Silmukka ratkaistaan kutsumalla vuorotellen moduleita action_analysis ja lokusanalysis. Lokusanalyysillä luodut rajoitukset ratkaistaan välittömästi ennen siirtymistä takaisin toiminta-analyysiin. Lopuksi jälleen tarvittaessa vapautetaan väliaikainen kiinnitys.

    Jos rajoituslista tyhjenee, systeemi on ratkaistu. Muuten toistetaan koko prosessi. Mikäli silmukkaan ei saada ratkaistua, on ongelma ylirajoitettu.

    Kun systeemi ratkaistaan ensimmäisen kerran, rajoitusten ratkaisujärjestys talletetaan. Sitä käytetään myöhemmillä ratkaisukerroilla ratkaisun nopeuttamiseksi. Järjestyksessä määritellään myös, mitkä peräkkäiset rajoitukset kuuluvat jäykkään pariin ja mitkä jäykkään silmukkaan.

  • write_result:

    Tätä funktiota kutsutaan so_solvesta ratkaisun päätyttyä. Täällä täytetään jokaista geomia kohti vähintään yksi kinLink-struktuuri. Common objektin ollessa kyseessä tarvitaan geomin markkereiden määrästä riippuva määrä struktuureja. Jokaista geomia kohti joudutaan siis laskemaan vähintään struktuuri, joka sisältää sijainnin, joka ACIS-mallin kyseessä ollessa saadaan kääntäjän lisäämästä mallin lokaalia origoa edustavasta markkerista ja kaksi pyörityskulmaa, joiden avulla kappale saadaan oikeaan asentoon. Kaksi pyöritystä riittää, sillä ne tapahtuvat vapaasti määriteltyjen akselien ympäri, jotka myös lasketaan. Common objektin tapauksessa siis lasketaan myös pituus. Common objektin pyörityskulmat lasketaan hieman eri tavalla, sen symmetrisyydestä johtuen vain ensimmäinen kulma on välttämätön, toista tarvitaan kosmeettisista syistä.

    Tietorakenteet:

    Käyttää globaaleja rajoitusten ja geomien listoja. Niiden sisältö ja suhteet on selvitetty mallin kääntäjän ja ratkaisijan rajapinnan dokumentoinnin yhteydessä. Lisäksi myös luodut makrogeomit ovat listassa. Lopullisessa toteutusvaiheessa makrogeomeista saatetaan luoda puu, jonka avulla lienee mahdollista toteuttaa eräs algoritmin toiminnallinen yksityiskohta.

    Algoritmit:

    Algoritmien tarkemmat kuvaukset löytyvät Kramerin kirjasta.

    Testattavuus:

    Kokeillaan erilaisia mekanismeja. Todetaan, että ne saadaan ratkaistua silloin kun järjestelmän tulee siihen pystyä, ja että ne toimivat oikein.

    Virhetilanteet:

    Jos ei voida täyttää enää yhtäkään rajoitusta vaikka rajoituslista ei ole tyhjä, palautetaan epätosi. Joko ongelma oli ylirajoitettu, alirajoitettu tai sen ratkaisuun tarvittavaa suunnitelman osaa tai lokusleikkausta tai silmukka ei ollut analyyttisesti ratkeava. Redundantit rajoitukset eivät häiritse algoritmia.


    Moduli: find_ridig_chain

    Tehtävä:

    Etsii geomiparin, jonka väliset rajoitukset kiinnittävät geomit toistensa suhteen.

    Tiedostot:

    Rajapinta:

    Modulia kutsutaan main_loop-modulista.

    Deque *find_ridig_chain();
    

    Kutsuu moduleita:

    Toiminta:

    Laittaa muistiin osoittimen ensimmäiseen rajoitukseen. Tutkii, mitä geomeja ensimmäinen rajoitus, jota ei ole merkitty tutkituksi, koskee. Etsii kaikki muutkin samoja geomeja koskevat rajoitukset kirjoittaen osoittimet niiden lista-alkioihin erilliseen listaan. Tutkitut rajoitukset merkataan tutkituiksi. Jos rajoitukset riittävät kiinnittämään geomit toistensa suhteen, palauttaa luodun listan. Muuten lisää rajoitukset takaisin annetun listan perään ja aloittaa alusta. Jos kaikki rajoitukset on tutkittu, palauttaa NULL:n. Kramerin kirjassa luetellaan kaikki minimaaliset jäykän parin määrittävät rajoitukset. Tällä hetkellä käytetään hieman erilaista menetelmää, joka antaa oikean vastauksen, kokeilluissa tilanteissa, mutta se on syytä muuttaa viimeistään lopulliseen versioon.

    Tietorakenteet:

    Käyttää listaa kaikista rajoituksista ja kokoaa toiseen listaan tietyn geomiparin välisten rajoitusten sijainteja rajoituslistassa.

    Algoritmit:

    On tiedettävä, onko geomipari jäykkä kun sen geomien välillä on tietyt rajoitukset. Tähän löytyy Lisp-algoritmi Kramerin kirjasta. Kirjassa esitetään myös kaikki minimaaliset rajoitusjoukot, jotka tekevät geomiparista jäykän. Tehdään taulukko, joka sisältää nämä rajoitusjoukot, ja tarkistetaan sisältääkö geomien välinen rajoitusten joukko jonkin näistä minimaalisista joukoista.

    Testattavuus:

    Syötetään sisään erilaisia rajoituslistoja, ja tarkistetaan, että löydetään kaikki jäykät parit, eikä mitään muuta kuin jäykät parit.

    Virhetilanteet:



    Moduli: find_and_choose_loop

    Tehtävä:

    Etsii rajoitusten muodostamat silmukat, ja palauttaa näistä sellaisen, joka on jäykkä, eli sillä ei ole sisäisiä vapausasteita.

    Tiedostot:

    Rajapinta:

    Modulia kutsutaan main_loop-modulista.

    struct loop *find_and_choose_loop()
    
    Loop-struktuuri sisältää silmukkaan kuuluvat makrogeomit ja rajoitukset.

    Kutsuu moduleita:

    Toiminta:

    Luo jokaiseen makrogeomiin listan, johon kuuluvat osoittimet kaikkiin niihin geomeihin, jotka ovat yhteydessä tähän geomiin jonkin rajoituksen välityksellä. Tämä tapahtuu käymällä läpi rajoituslista. Etsii silmukat Kramerin kirjassa esitetyn vaiheittaisen leveyshakualgoritmin avulla. Laittaa silmukoihin kuuluvat geomit omiin listoihinsa. Valitsee kustakin useassa eri muodossa esiintyvästä silmukasta tietyn yksikäsitteisen version. Etsii silmukkaan kuuluvat rajoitukset. Tutkii kirjassa esitetyllä algoritmilla, onko kysymyksessä tasosilmukka. Tätä tietoa hyväksi käyttäen testaa silmukan jäykkyyttä kirjassa esitetyillä kaavoilla. Palauttaa ensimmäisen löydetyn jäykän silmukan makrogeomit ja rajoitukset.

    Tietorakenteet:

    Geomien vierekkäisyysmatriisi, joka koostuu geomikohtaisista vierekkäisyyslistoista.

    Listojen lista, joka sisältää kaikkien silmukkaehdokkaitten makrogeomit.

    Listojen lista, joka sisältää kaikki kanonisoitujen silmukoiden makrogeomit.

    Lista, joka sisältää kulloinkin tutkittavan kanonisen silmukan kaikki rajoitukset.

    Algoritmit:

    Katso toiminta. Tarkempi selitys löytyy Kramerin kirjasta pseudokoodina.

    Testattavuus:

    Käytetään sopivia testimekanismeja, ja tarkistetaan, että kaikki silmukat ja vain ne löydetään ja oikea silmukka tulee valituksi.

    Virhetilanteet:



    Moduli: action_analysis

    Sisältää modulikaaviossa näkyvät modulit "Suunnitelman osat", "Geomien liikutus" ja "Invarianttien päivitys". Ne on merkitty modulikaavioon toiminta-analyysin sisältävän ohjelmamodulin sisäisen rakenteen esilletuomiseksi.

    Tehtävä:

    Täyttää annetun rajoituksen, määrää siirretyn markkerin geomin vapausasteet ja luo siirretyn geomin markkereille lokukset.

    Tiedostot:

    Rajapinta:

    Modulia kutsutaan main_loop-modulista.

    bool Constraint::Solve()
    void Geom::translateGeom(Vector *translation_vector)
    void Geom::rotateGeom(Marker *center, float angle)
    Vector *getAxis(Vector *v1, Vector *v2, double angle)
    

    Kutsuu moduleita:

    Toiminta:

  • bool Constraint::Solve()
  • Suunnitelman osat:

    Tarkistaa, että toinen geomeista on riittävästi rajoitettu. Ratkaisee tietyntyyppisen rajoituksen geomille käyttäen suunnitelman osaa, joka määrittää toimenpiteet ko. tyyppisen rajoituksen ratkaisemiseksi ko. tavalla rajoitetulle geomille. Kaikkiin mahdollisiin tilanteisiin ei tarvitse määrittää suunnitelman osaa, vaan ne selvitetään asettamalla rajoituksia rajoitusten toteutusjärjestykselle. Päivittää siirretyn geomin vapausasteet ja sen markkerien invariantit. Kustakin markkerista pidetään yllä tietoja siitä, ovatko sen paikka, x-akseli ja z-akseli invariantteja. Lisäksi tarvittaessa päivitetään akseli, jonka ympäri geomi saa pyöriä, piste jonka ympäri se saa pyöriä ja taso, jossa se saa liikkua.

    Jos rajoitus saatiin täytettyä, palautetaan TRUE, muuten FALSE.

  • translateGeom:

    Siirtää geomia siirtovektorin "translation_vector" osoittamalla tavalla. Siirto toteutetaan siirtämällä geomin kaikkia markkereita ko. vektorin verran.

  • rotateGeom

    Pyörittää geomia kulman "angle" verran vektorin "axis" määrittämän akselin ympäri. Vapaan akselin ympäri pyöritys toteutetaan viidellä pyörityksellä. Kaksi ensimmäistä pyöritystä ovat sellaisia, että annettu akseli saadaan globaalin koordinaatiston z-akselin suuntaiseksi. Kolmas pyöritys pyörittää geomia annetun kulman verran z-akselin ympäri. Kaksi viimeistä pyöritystä toteuttavat päinvastaisen muunnoksen kuin kaksi ensimmäistä. Algoritmi vapaan akselin ympäri pyörittämiseksi löytyi kirjasta Hearn ja Baker: Computer Graphics.

    Pyörittää ensin kaikkien geomin markkereiden koordinaatistovektoreita ja siirtää sitten markkereita akselin ja markkerin etäisyyden keskusmarkkerista määrittämällä ympyrällä kulman "angle" verran.

  • getAxis

    Laskee pyöritysakselin pyöritettävän vektorin, sen vektorin, jonka suuntaiseksi edellinen vektori on saatava ja em. vektorien välisen kulman avulla. Normaalisti haluttu vektori saadaan laskemalla ristitulo vektoreiden välillä, mutta jos vektoreiden välinen kulma on 180 astetta, lasketaan jokin pyöritettävää vektoria vastaan kohtisuora vektori laskemalla ristitulo pyöritettävän vektorin ja jonkin muun vektorin kanssa, joka ei saa olla yhdensuuntainen pyöritettävän vektorin kanssa.

    Algoritmit:

    Suunnitelman osat yhdessä muodostavat algoritmin geomien siirtämiseksi ja pyörittämiseksi siten, että rajoitukset saadaan täytettyä. Esimerkiksi jos rajoitetaan markkeri kiinnitetyn markkerin määrittämälle suoralle, ja edellinen markkeri voi liikkua jossain tietyssä tasossa, niin lasketaan tason ja suoran leikkauspiste. Seuraavaksi mitataan vektori tasoon rajatusta markkerista leikkauspisteeseen ja siirretään sen geomin kaikkia markkereita saadun vektorin verran. Geomille jää jäljelle sen pyörimisvapausasteet. Olettaen, että geomilla on kolme pyörimisvapausastetta, ainut markkereille asetettava invariantti on leikkauspisteeseen siirretyn markkerin paikkainvariantti.
    Mikäli suora sijaitsi tasossa, projisoidaan tasossa liikkuva markkeri suoralle ja siirretään geomia kuten edellä. Geomille jää sen pyörimisvapausasteiden lisäksi suoran suuntainen siirtovapausaste ja markkereille ei tule yhtään invarianttia.
    Mikäli suora ei leikkaa tasoa, on ongelma ylirajoitettu eikä sitä voida ratkaista.

    Testattavuus:

    Luodaan yksinkertaisia muutaman geomin systeemejä siten, että rajoituksia täytettäessä joudutaan käyttämään juuri testattavaa suunnitelman osaa.

    Virhetilanteet:

    Jos ongelma on ylirajoitettu tulostetaan virheilmoitus ja palautetaan epätosi. Näin tehdään myös, jos tarvittavaa suunnitelman osaa ei ole toteutettu tai sitä ei voida toteuttaa.


    Moduli: locus_analysis

    Tehtävä:

    Pyritään korvaamaan muuten ratkeamattomat rajoitukset ratkeavilla tutkimalla markkereiden lokuskäyrien ja -pintojen leikkauksia.

    Tiedostot:

    Rajapinta:

    Modulia kutsutaan main loop-moduulista.

    bool Constraint::locusAnalysis()
    

    Kutsuu moduleita:

    Toiminta:

    Jos joidenkin markkerien välillä on yhtenevyysrajoitus, inline-rajoitus tai asentoa rajoittava rajoitus niille voidaan saada yhteinen sijainti tai asento laskemalla lokusten leikkaus.

    Jos tutkittava rajoitus voidaan ratkaista rajoitukseen liittyvien markkereiden lokuskäyrien tai -pintojen leikkauksen avulla, luodaan nämä lokuskäyrät tai -pinnat ja lasketaan leikkaus.
    Tämän jälkeen luodaan markkeri edustamaan saatua yhteistä leikkauspistettä ja generoidaan uudet rajoitukset markkerien määräämiseksi saatuun leikkauspisteeseen.
    Jos saatiin tulokseksi käyrä eikä pistejoukko, se vain kirjoitetaan markkerien lokuksiksi.

    Leikkausten laskuun käytetään intersections-moduulin funktioita. Leikkauspisteen valinta tapahtuu choice-moduulissa.

    Tietorakenteet:

    Algoritmit:

    Mikäli rajoituksen markkereilla on jokin käyrä- tai pintalokus, todetaan saadaanko niiden leikkauksena äärellinen pistejoukko. Mikäli saadaan, kutsutaan vastaavaa leikkaus-rutiinia ja luodaan kaksi uutta rajoitusta, jotka määräävät markerit saatuun leikkauspisteeseen ja palautetaan tosi. Muuten palautetaan epätosi. Kahden pinnan leikkauksena saatu käyrä talletetaan markkerien lokuksiksi, tässä tapauksessa muita edellämainittuja toimenpiteitä ei suoriteta.

    Testattavuus:

    Annetaan modulille rajoituksia, joiden markkereilla on tietyt lokukset ja tarkistetaan, että saadaan oikea vastaus.

    Virhetilanteet:



    Moduli: measurements

    Tehtävä:

    Lasketaan pisteiden välisiä vektoreita, vektorien pituuksia, vektorien välisiä kulmia ja pisteiden projektioita käyrille ja pinnoille. Sisältää myös leikkausten laskuun liittyviä funktioita.

    Moduuli on käytännöllisesti katsoen täysin Timo Kallosen toteuttama.

    Tiedostot:

    Rajapinta:

    Modulia kutsutaan action_analysis-moduulista.

    float get_scalar_angle(Vector*, Vector*)
    float get_length(Vector*)
    Vector *get_vector(Point*, Point*)
    Point *project_point_line(Point*, Line*)
    Point *project_point_circle(Point*, Circle*)
    Point *project_point_plane(Point*, Plane*)
    Point *project_point_sphere(Point*, Sphere*)
    
    Timo Kallonen on dokumentoinut tästä puuttuvat funktiot.

    Kutsuu moduleita:

    Toiminta:

    Sisältää funktiot erityyppisten projektioiden laskemista, vektorien välisen kulman laskemista, vekrorin pituuden laskemista ja kahden pisteen välisen vektorin laskemista varten.
    Esimerkiksi project_point_line projisoi annetun pisteen annetulle suoralle ja palauttaa projektiopisteen. Nimistä selvinnee kunkin funktion täsmällinen käyttötarkoitus. Moduuli sisältää myös leikkausten laskuun liittyviä funktioita.

    Tietorakenteet:

    Algoritmit:

    Testattavuus:

    Testataan funktio kerrallaan käsin lasketuilla esimerkeillä, että saadaan oikeat tulokset.

    Virhetilanteet:



    Moduli: intersections

    Tehtävä:

    Lasketaan pisteiden, käyrien ja pintojen leikkauksia. Moduli on täysin Timo Kallosen toteuttama.

    Tiedostot:

    Rajapinta:

    Modulia kutsutaan action_analysis-, ja locus_analysis- moduuleista.

    Point *intersect_point_point(Point*, Point*)
    Point *intersect_point_line(Point*, Line*)
    Point *intersect_point_circle(Point*, Circle*)
    Point *intersect_point_plane(Point*, Plane*)
    Point *intersect_point_sphere(Point*, Sphere*)
    Point *intersect_line_line(Line*,Line*)
    Point *intersect_line_circle(Line*, Circle*)
    Point *intersect_line_plane(Line*, Plane*)
    Point *intersect_line_sphere(Line*, Sphere*)
    Point *intersect_circle_circle(Circle*, Circle*)
    Point *intersect_circle_plane(Circle*, Plane*)
    Point *intersect_circle_sphere(Circle*, Sphere*)
    Point *intersect_plane_plane(Plane*, Plane*)
    Point *intersect_plane_sphere(Plane*, Sphere*)
    Point *intersect_sphere_sphere(Sphere*, Sphere*)
    (Monet luokat sisältävät lipun degeneroitunutta tilannetta varten. Siis esimerkiksi jos suorien leikkauksena saadaan koko suora, eli ne olivat samat.)
    

    Kutsuu moduleita:

    Toiminta:

    Kukin funktio laskee annettujen aliavaruuksien leikkauksen käyttäen yleisiä kaavoja.

    Tietorakenteet:

    Algoritmit:

    Testattavuus:

    Testataan funktio kerrallaan käsin lasketuilla esimerkeillä, että saadaan oikeat tulokset.

    Virhetilanteet:



    Moduli: choice

    Tehtävä:

    Valitaan sopiva piste leikkausfunktiolta saadusta pistejoukosta.

    Tiedostot:

    Rajapinta:

    Modulia kutsutaan intersections-moduulista.

    Point *GetChoice(Point *Choice1, Point *Choice2, Marker *moving)
    void sendGroundedGeoms()
    Point *ApproxChoice(Point *intersection1, Point *intersection2, Marker *moving)
    

    Kutsuu moduleita:

  • Renderer

    Toiminta:

  • GetChoice:

    Valitsee pisteen interaktiivisesti. Ensin tulostetaan visualisoijan ikkunaan ainakin kiinnitetyt geomit ja väliaikaisesti kiinnitetyt geomit. Tulostetaan myös valintapisteitä edustavat merkit. Varsinainen valinta suoritetaan käyttöliittymäikkunassa.

  • ApproxChoice

    Sillä kierroksella, kun interaktiivinen valinta on suoritettu, valitsee sen pisteen, jonka etäisyys edellisellä kierroksella valittuun pisteeseen on pienin.

    Seuraavilla ratkaisukerroilla valitaan aina se vaihtoehto, jonka toteuttaminen minimoi markkereiden siirtoon käytettävän siirtovektorin ja vastaavan edellisen siirtovektorin erotuksen. Selvemmin sanoen markkerit pyrkivät vastustamaan nopeusvektorinsa muutosta. Tällä pyritään välttämään mekanismin simuloinnissa tapahtuvia "hyppäyksiä" ja muita mekanismin luonnollisen toiminnan vastaisia ratkaisun valintoja. Yritetään siis pitää mekanismin toiminta mahdollisimman "jatkuvana".

    Tietorakenteet:

    Algoritmit:

    Funktio ApproxChoice valitsee palautettavan pisteen minimoimalla siirrettävän markkerin nopeusvektorin muutosta.

    Testattavuus:

    Nähdään käytännössä, pysyykö mekanismien toiminta jatkuvana, ja että interaktiivinen valinta toimii odotetulla tavalla.

    Virhetilanteet:


    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |

    3.6.5. Visuaalisen mallin määrittelijä modulijako

    Kuva visuaalisen mallin määrittelijän modulikaaviosta (postscript).


    Moduli: defModel

    Tehtävä:

    Moduli, jossa visuaalinen malli määritellään.

    Tiedostot:

    Rajapinta:

    int main (int argc, char **argv);
    

    Kutsuu moduleita:

    Toiminta:

    Moduli luo ACIS:illa visuaalisen mallin. Moduli kutsuu polygModel:ia, joka tallentaa ACIS-mallin polygonimuodossa tiedostoon.

    Modulille on vaihtoehtoisia toteutuksia, joista kaksi toteutetaan.

    Ensimmäiessä toteutuksessa defModel jaetaan osamoduleihin: defMain, defModel1, defModel2, defModel3, ...
    defMain alustaa ACIS:in ja polygonimuuntimen, ja kutsuu kutakin defModel<n>:ää. Jokaisessa defModel<n>:ssä on yhden ACIS-mallin määrittely. defMain tallettaa kunkin mallin omaan tiedostoon kutsumalla polygModel:in polyg_save:a.

    Toisessa toteutuksessa defModel saa argumenttina kaksi tiedostonnimeä. Ensimmäinen on tiedosto, jossa on ACIS-formaatilla talletettu visuaalinen malli. Toinen on kohdetiedosto, johon polygonimalli tallennetaan. Tämä toteutus antaa mahdollisuuden polygonisoida ulkopuolisen ohjelman tekemiä ACIS-malleja, mikäli tämä on tallennettu tiedostoon ACIS-formaatilla.

    Lisäksi on mahdollista, että käyttäjä laatii ao. modulin tai lisää defModel<n>:eita.

    Virhe- ja poikkeustilanteet:

    Mikäli jokin ACIS:in API-kutsu tai polygonisoijan kutsu antaa paluuarvona ERROR, tulostetaan virheilmoitus, joka kertoo mikä käsky ei onnistunut. Lisäksi keskeytetään ohjelman suorittaminen.

    Testattavuus:

    Ei polygonisoida mallia vaan talletetaan se ACIS-formaatilla tiedostoon, ja katsotaan "ACIS Test Harness":illa onnistuiko mallin määrittely.

    Moduli: defMain

    Tehtävä:

    Alustaa ACIS:in ja polygonisoijan sekä kutsuu defModel<n>:eitä.

    Tiedostot:

    Rajapinta:

    int main (int argc, char **argv);
    

    Kutsuu moduleita:

    Toiminta:

    Moduli alustaa ACIS:in ja polygonisoijan. Moduli sisältää silmukan, joka kutsuu vuorollaan jokaista defModel<n>:ää. Moduli saa defModel<n>:iltä paluuarvona "body":n jonka se tallettaa polygonimuodossa tiedostoon kutsumalla polyg_save:a.


    Moduli: defModel<n>

    Tehtävä:

    Moduli, jossa n:s visuaalinen malli määritellään.

    Tiedostot:

    Rajapinta:

    BODY* defModel<n> ();
    

    Toiminta:

    Moduli on aliohjelma, joka luo ACIS:illa visuaalisen mallin. Modulin paluuarvo on pointteri malliin.


    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |

    3.6.6. Polygonisoijan modulijako

    Kuva polygonimuuntimen modulikaaviosta (postscript).


    Moduli: polygMain

    Tehtävä:

    Moduli muodostaa polygonisoijan rajapinnan.

    Tiedostot:

    Rajapinta:

    int polyg_init (float surf_dev, float norm_dev);
    int polyg_attr (float surf_dev, float norm_dev);
    int polyg_save (char *filename, BODY* body);
    int polyg_terminate ();
    

    Kutsuu moduleita:

    Toiminta:

    Polygonimuunnin käyttää ACIS Facetter Husk:ia polygonien tekemiseen. "polyg_init" käynnistää Facetterin ja "polyg_terminate" sammuttaa sen. Tästä syystä visuaalisen mallin määrittelijä, "defModel", ei saa käyttää Facetteria "polyg_init" ja "polyg_terminate" -käskyjen välillä.

    Facetterin käynnistämisen lisäksi "polyg_init" määrittelee facetterille "refinements"-optioita, jotka vaikuttavat muunnoksessa syntyvän polygon-mesh:in tarkkuuteen ja nurkkapisteiden lukumäärään. "refinements"- optioita voi muuttaa myös "polyg_attr" -käskyllä.

    "polyg_save" muodostaa visuaalisesta mallista polygon meshin, ja kutsuu polygSave-modulia.

    Virhe- ja poikkeustilanteet

    Mikäli rajapintaan kuuluva funktio ei onnistu, annetaan paluuarvona ERROR.


    Moduli: polygSave

    Tehtävä:

    Tallentaa polygon meshin tiedostoon.

    Tiedostot:

    Rajapinta:

    int polyg_mesh_to_file (POLYGON_POINT_MESH*& pmesh);
    

    Toiminta:

    Lukee polygon meshin ACIS-tietorakenteesta ja tallentaa sen polygoni kerrallaan tiedostoon. Kustakin polygonista tallennetaan sen jokaisen nurkkapisteen sijainti ja normaalivektori.

    Testattavuus

    Polygonimallinen tiedosto on tekstimuotoinen, joten ensimmäisenä testinä luodaan polygonimalli kuutiosta ja katsotaan, onko polygonitiedostossa virheetön malli.


    3.6.7. Prosessien välinen kommunikointi

    Simulaattorin kahden prosessin, instantioijan ja visualisoijan, välinen tiedonsiirto hoidetaan viestien välityksellä. Unix tarjoaa viestien välitykseen systeemikutsut "msgget", "msgsend", "msgrcv" ja "msgctl".

    3.6.7.1. kineMessage

    KineMessage on kirjasto, joka toteuttaa viestin välityksen simulaattorin kahden prosessien välillä käyttämällä Unix:in systeemikutsuja.

    Kirjasto sisältää funktiot:

    Koska kineMessage välittää datan aina merkkijonona char *messagetext, täytyy viestin vastaanottajan tietää minkä tyyppistä dataa lähettäjä on lähettänyt. Tämä näkyy viestikohtaisista tietorakenteista.

    3.6.7.2. Viestien dataosan tietorakenteet


    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |

    5. Käyttöohjeet

    5.1. Instantioija

    Instantioijan ikkunasta ohjataan simulaatiota antamalla parametreille arvoja ratkaistavaksi sekä käynnistämällä tai keskeyttämällä animointi.

    Animoinnin ollessa käynnissä ainoa mahdollinen käsky on pysäytys "Stop"-nappia painamalla. Tällöin muut toiminnot aiheuttavat virheilmoituksen Messages-ikkunaan.

    Tehty valinta näkyy tummana neliönä, valitseminen tapahtuu vasemmalla hiiren napilla. Ainoa varmistava dialogi tulee lopetus eli "Quit" -käskystä, muuten valinta vaikuttaa heti instantioijassa.

    *
    Kuva 1. Instantioijan ikkuna.

    5.1.1 File-alasvetovalikko

    Ilmestyy painamalla hiiren vasemmalla napilla valikon nimeä "File".

    Toiminnot:

    *
    Kuva 2. Tiedostonselausikkuna.

    5.1.2 Funcs-alasvetovalikko

    Ilmestyy painamalla hiiren vasemmalla napilla valikon nimeä "Funcs".

    Valikossa näkyvät valittavana olevat parametreihin liitettävät syöttöfunktiot. Kun parametri on valittu parametrilistasta, tästä valikosta hiirellä valitsemalla saa muutettua parametrin syöttöfunktiota. Muutos näkyy parametrilistassa. Oletusarvoisena funktiona parametrille on suora muutos nykyisestä parametrin arvosta haluttuun arvoon. Muutos astuu voimaan muissa osajärjestelmissä vasta painettaessa "Start"-nappia.

    *
    Kuva 3. Parametrin valinta.

    5.1.3 Napit

    Toimivat välittömästi painettaessa niitä hiiren vasemmalla napilla.

    5.1.4 Parametrilista

    Parametrilistasta näkee ratkaisijan käyttämät viimeisimmät arvot.

    Parametrilistasta voidaan valita rivi tietyn parametrin asetusarvon, syöttöfunktion ja funktion argumentin antamiseksi.

    Parametrilista koostuu järjestyksessä seuraavista tiedoista:

    Asetusarvo annetaan valitsemalla hiirellä ensin muutettava parametrin rivi, sekä aktivoimalla tämän jälkeen asetusarvon kenttä. Kenttään tulee näkyviin nykyinen arvo sekä vilkkuva kursori. Tällöin uusi arvo voidaan kirjoittaa näppäimistöltä vanhan tilalle. Asetus lopetetaan Enteriä tai rivinvaihtoa painamalla, jolloin valinnan osoittava neliö poistuu. Funktion argumentti annetaan samalla periaatteella argumentin kenttään.

    Muutos astuu voimaan muissa osajärjestelmissä vasta painettaessa "Start"-nappia.

    5.1.5 Leikkauspisteiden valinta

    Ratkaisijan pyytäessä käyttäjää valitsemaan leikkauspistettä tulostuu Messages-ikkunaan valintateksti sekä koordinaattipisteet omille riveilleen. Käyttäjän on valittava näistä yksi ratkaisun löytämiseksi.

    Valinta tapahtuu yksinkertaisesti klikkaamalla sitä riviä, jolle haluttu piste on tulostettu.

    *
    Kuva 4. Leikkauspisteiden valintatilanne.

    5.1.6 Moodin valinta

    Ratkaisun animointiin vaikuttavat moodit Päällä oleva moodi näkyy "Moodi:"-alasvetovalikon nimessä.

    Valinta tapahtuu valitsemalla Moodi-alasvetovalikosta jokin rivi, jolloin kyseisen moodin nimi vaihtuu alasvetovalikon otsikkoon. Moodin valinta astuu voimaan vasta painettaessa Start-nappia.


    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |

    5.2. Visualisoija

    Visualisoijan ikkunassa on mahdollista pyörittää ja zoomata mallia hiirellä sekä animaation aikana että mallin ollessa pysähdyksissä. Popup-menuista löytyy lisäksi toiminnot koordinattiakselien kytkemiseksi päälle/pois sekä animaation pysäyttämiseksi.

    5.2.1. Popup-menut

    Popup-menut ilmestyvät näkyviin painamalla hiiren oikeanpuolimmaista nappia visualisoijan ikkunassa.

    *
    Kuva 5. Popup menu.

    Toiminnot:

    5.2.2. Mallin katselu

    Hiirellä voi pyörittää ja zoomata mallia pitämällä vasemman puoleista tai keskimmäistä nappia pohjassa ja liikuttamalla hiirtä.

    Toiminnot vasen nappi pohjassa:

    Toiminnot keskimmäinen nappi pohjassa:

    *
    Kuva 6. Visualisoijan ikkuna.


    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |

    5.3. Määrittelykieli

    Määrittelykielen 1. esimerkki (postscript).
    Määrittelykielen 2. esimerkki (postscript).

    Semantiikkaa

    [ ] merkkien sisällä olevat termit voi jättää pois
    < > merkkien sisällä olevia termejä ei saa jättää pois


    Markerin määrittely

    marker <marker> (<global_coord>);
    

    Parametrit:

    <marker>
    markerin nimi
    <global_coord>
    markerin koordinaatisto globaalissa koordinaatistossa
    (ks. kohta kordinaatiston määrittely)

    Esimerkki:

    marker piste_a (4.6, 5, 0, 45, 45, 0);
    marker piste_b (5, 0, 0, 90, 90, 90);
    

    Linkin määrittely

    link <link> (<global_coord>) [visual_model]
    {
        <marker> (<local_coord>);
        <marker> (<local_coord>);
        ...
    }
    

    Parametrit:

    <link>
    linkin nimi
    <global_coord>
    linkin koordinaatisto globaalissa koordinaatistossa
    (ks. kohta kordinaatiston määrittely)
    [visual_model]
    visuaalisen mallin id_numero tai tyyppi

    Visuaalisen mallin tyypit ovat

    Mikäli mallityyppiä tai id-numeroa ei anneta, on linkki näkymätön.
    <marker>
    markerin nimi
    <local_coord>
    markerin koordinaatisto linkin lokaalissa koordinaatistossa
    (ks. kohta kordinaatiston määrittely)

    Esimerkki:

    link l1 (undef) 3 
    {
        piste_a (ident);
        piste_c (-4, 1, 0, 45, 90, 90);
        piste_d (4, 1, 0, -45, 90, 0);
    }
    
    link l2 (ident) 4
    }
        piste_e (ident);
    }
    

    Constraintin määrittely

    Sallitut muodot staattiselle rajoitukselle:
    constr <constr> <type> (<marker-1>, <marker-2>, <param>);
    constr <constr> <type> (<marker-1>, <marker-2>);
    
    Sallittu muodot dynaamiselle rajoitukselle:
    dynconstr <constr> <type> (<marker-1>, <marker-2>, <param>);
    

    Parametrit:

    <constr>
    rajoituksen nimi
    <type>
    rajoituksen tyyppi

    Rajoitustyypit ovat:

    <marker-1>, <marker-2>
    markerien nimet

    Jonkintyyppisissä rajoituksissa markerit ovat epäsymmetrisessä asemassa. Esimerkiksi inline-rajoituksessa marker-1 on marker-2:en z-akselin suuntaisella marker-2:en origoa leikkaavalla suoralla.

    huom. Jotta rajoitus voi viitata markeriin, täytyy markeri olla ensin määritelty. Markeri määritellään joko "marker"-käskyllä tai mainitsemalla markeri "link"-käskyn marker-listassa.

    <param>
    tyyppiin liittyvä parametri

    Esimerkki:

    constr raj_a coincident (piste_a, piste_e);
    dynconstr raj_b offset-x (piste_a, piste_b, 20);
    


    Valinta vaihtoehtoisista ratkaisuista

    solution <count>;
    

    Parametrit:

    <count>
    vaihtoehdon numero

    Jos kinemaattisella mallilla on useita ratkaisuja, esitetään n:s ratkaisu.

    Esimerkki:

    solution 2;
    


    Visuaalisen mallin tiedoston määrittely

    load "<file_name>" <id_number> [color];
    

    Parametrit:

    <file_name>
    tiedoston nimi
    <id_number>
    visuaalisen kappaleen id-numero
    <color>
    Värin nimi

    huom. Jotta väriin voi viitata, se täytyy ensin määritellä.
    (ks. värin määrittely)

    Mikäli väriä ei anneta, on visuaalisen mallin väri valkoinen.

    Esimerkki:

    load "robotti.kasi.poly" 4 green;
    


    Värin määrittely

    color <color> (<red>, <green>, <blue>);
    

    Parametrit:

    <color>
    värin nimi
    <red>, <green>, <blue>
    värin RGB-arvot
    Väri määritellään antamalla väreille "red", "green" ja "blue" lukuarvot. Luvut voivat olla välillä [0..1]. Esimerkiksi (0,0,0) on musta, (1,1,1) on valkoinen ja (0,0,1) on sininen.

    Esimerkki:

    color green (0.1, 1, 0.1);
    
    

    Koordinaatiston määrittely

    Koordinaatistomuunnos määrittelee lokaalin koordinaatiston globaalissa tai hierarkisesti ylemmässä lokaalissa koordinaatistossa. Koordinaatistomuunnoksen voi määrittää kokonaan, osittain tai ei ollenkaan.

    Seuraavat muodot ovat sallittuja globaalin koordinaatiston muunnoksessa:

    (<x-coord>, <y-coord>, <z-coord>, <alpha>, <beta>, <gamma>)
    (ident)
    (undef)
    
    Seuraavat muodot ovat sallittuja lokaalin koordinaatiston muunnoksessa:
    (<x-coord>, <y-coord>, <z-coord>, <alpha>, <beta>, <gamma>)
    (<x-coord>, <y-coord>, <z-coord>, autodirect-z)
    (<x-coord>, <y-coord>, <z-coord>, autodirect-x)
    (ident)
    

    Parametrit:

    <x-coord>, <y-coord>, <z-coord>
    x-, y- ja z-koordinaatit

    Koordinaatit määrittävät lokaalin koordinaatiston origon globaalissa tai hierarkisesti ylemmässä lokaalissa koordinaatistossa.

    <alpha>, <beta>, <gamma>
    koordinaatiston akselien suunnan määrittely

    Akselien suunnanmuutos tapahtuu kiertämällä koordinaatistoa ensin alpha-astetta x-akselin ympäri, sitten beta-astetta y-akselin ympäri ja lopuksi gamma-astetta z-akselin ympäri. Kiertosuunta on kaikissa muunnoksissa koordinaatiston kiertoakselin suhteen vastapäivään.

    Vakiot:

    ident
    identity-koordinaatistomuunnos

    Määriteltävän lokaalin koordinaatiston origo on globaalin tai hierarkisesti ylemmän koordinaatiston origossa. Akselien suunnat ovat samat molemmissa koordinaatistoissa.

    undef
    koordinaatistomuunnosta ei ole määritelty
    autodirect-z
    z-akselin automaattimääritys

    Markerien z-akselit asetetaan keskenään samansuuntaisiksi ja kohtisuoraksi markerien väliseen janaan.

    autodirect-x
    x-akselin automaattimääritys

    Markerien x-akselit asetetaan osoittamaan toisiaan.

    5.4. Konvertteri

    Konvertteri muuttaa ACIS-formaatin mukaisia tiedostoja Kinesimun ymmärtämään polygonimuotoon.

    convert [-n ] [-s surface-deviation] infile outfile

    normal-deviation: kulmapisteiden normaalivektoreiden maksimivirhe asteissa
    surface-deviation: polygonisoidun pinnan sijainnin maksimivirhe suhteessa mallin kokoon.


    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |

    4. Käsiteluettelo


    | Sisällysluettelo | Luku 1 | Luku 2 | Luku 3 | Luku 4 | Luku 5 | KineSimu |