Kinesimu
Järjestelmäkäsikirja
$Id: jk.html,v 1.55 1996/02/29 11:14:24 jvanhane Exp $
Muutosohjeet
Sisällysluettelo
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
- määrittelykielen, jolla käyttäjä voi määritellä kinemaattisia
malleja
- mahdollisuuden liittää ACIS-ohjelmistolla luotuja geometrisiä
malleja kinemaattisen mallin linkkeihin visualisointivaiheessa
- geometristen rajoitusten ratkaisumenetelmän, joka pystyy laskemaan
kinemaattisen mallin liikkeen
- animaation mallin liikkeestä
| Sisällysluettelo | Luku 1
| Luku 2 | Luku 3
| Luku 4 | Luku 5
|
KineSimu |
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 |
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ä.
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 |
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 |
Järjestelmän osat ovat:
- Ratkaisijan, kääntäjän ja visualisoijan muodostama ohjelma, jota kutsutaan
jatkossa visualisoijaksi. Sen ikkunaan renderöidään simulaatio mallista.
- Instantioija, joka huolehtii varsinaisesta käyttöliittymäikkunasta.
- Konvertteri, joka muuntaa ACIS-ohjelmistolla tehtyjä 3D-malleja visualisoijan
ymmärtämään polygonimuotoon.
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 |
Kaikki ohjelmiston tiedostot ovat hakemiston kinesimu/ alla:
- source/ sisältää ohjelmiston lähdekoodin ja Makefilet.
Makefile (makefile, joka kutsuu muita makefilejä)
Makefile.p1 (visualisoijan makefile)
Makefile.p2 (instantioijan makefile)
Makefile.p3 (konvertterin makefile)
include/ (sisältää GLUT:n ja matriisikirjaston include-tiedostot)
lib/linglut.a (GLUT-kirjasto)
lib/matrix++.a (matriisi-kirjasto)
compiler/ converter/ instantiator/ intersections/ messages/ solver/ visualizer/
(lähdekoodihakemistoja)
- bin/ sisältää kääntämisen jälkeen järjestelmän ajettavat binäärit.
kinesimu (scripti, joka käynnistää koko ohjelmiston)
visual (visualisoijan binääri)
ins (instantioijan binääri)
convert (luo ACIS-formaatin tiedostosta polygonitiedoston)
polyg (luo ACIS:n API-kutsuilla koodatuista malleista polygonitiedostoja)
- docs/ sisältää manuaalit.
- examples/
polygons/sisältää polygonitiedostoja.
models/ sisältää määrittelykielellä
luotuja mekanismeja.
| Sisällysluettelo | Luku 1
| Luku 2 | Luku 3
| Luku 4 | Luku 5
|
KineSimu |
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 |
Järjetelmä lukee syötteenä määrittelykielellä tehtyjä tiedostoja
ja visuaalisia malleja sisältäviä polygonitiedostoja.
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 |
Järjestelmä koostuu seuraavista osajärjestelmistä:
- mallien kääntäjästä, joka tekee määrittelykielisestä tiedostosta
kinemaattista mallia esittävän tietorakenteen
- ratkaisijasta, joka ratkaisee linkien asennot tietyillä parametrien arvoilla
- visualisoijasta, joka sisältää kaikki mallin renderöintin liittyvät toiminnot ja
lisäksi se ohjaa prosessia 1
- instantioijasta, joka vastaa varsinaisesta käyttöliittymäikkunasta
- konvertterista, joka muuntaa 3D ACIS-malleja polygonimuotoon. Tämä on täysin erillinen
osa muusta ohjelmistosta.
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 |

Kuva 1. Tason 1 tietovirtakaavio
(kuva postscript muodossa).
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:
- LOAD, sisältää kinemaattisen mallin tiedostonimen, jonka käyttäjä haluaa ladata
- START, käskee aloittamaan animaation
- STOP, käskee pysäyttämään animaation
- QUIT, käskee poistumaan järjestelmästä
Visualisoija lähettää instantioijalle seuraavia viestejä:
- LOAD_OK, malli saatiin käännetyksi
- LOAD_FAILED, kääntäminen epäonnistui
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 .
Visualisoija kutsuu ratkaisijaa kolmessa eri tarkoituksessa:
- kun käyttäjä painaa START:ia kutsutaan so_init():ä, jotta ratkaisija
lukisi instantioijan lähettämän viestin PARAMS_FUNCS, joka sisältää
dynaamisille rajoituksille annetut alkuarvot ja muutosfunktiot.
- kun mallia animoidaan kutsutaan so_solve():a, joka palauttaa
kinLink tietorakenteen, joka sisältää linkkien id:t,
paikat ja asennot uuden ratkaisun jälkeen. Funktio palauttaa myös tiedon
siitä saavuttiko malli loppuasentonsa.
- kun käyttäjä painaa STOP:ia kutsutaan so_last():a, jotta ratkaisija
lähettäisi instantioijalle viestin LAST_VALUES, joka sisältää dynaamisten
rajoitusten arvot viimeisen ratkaisun jälkeen.
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ä.
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.
Instantioijalta ratkaisijalle tulevat viestit voivat olla seuraavia:
- PARAMS_FUNCS
Ratkaisija lukee instantioijalta tulevan viestin PARAMS_FUNCS, kun
käyttäjä käynnistää animaation. Viesti sisältää dynaamisten rajoitusten
alkuarvot sekä muutosfunktiot.
- CHOSEN
Instantioija lähettää valitun leikkauspisteen indeksin viestissä
CHOSEN, kun käyttäjä on tehnyt valinnan.
- MODE
Instantioija lähettää valitun moodin nimen aina Start-nappia
painettaessa.
Ratkaisija lähettää instantioijalle seuraavia viestejä:
- LAST_VALUES
Ratkaisija lähettää instantioijalle viestin LAST_VALUES, kun
malli saavuttaa lopputilansa tai käyttäjä pysäyttää animaation.
Viesti sisältää alussa annettujen dynaamisten rajoitusten loppuarvot.
- CHOOSE
Ratkaisija kysyy käyttäjältä haluttua leikkauspistettä lähettämällä
instantioijalle viestissä CHOOSE mahdollisten leikkauspisteiden
koordinaatit.
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 |
Instantioija on kokonaan oma prosessinsa, joka kommunikoi toisen prosessin
kanssa viestien välityksellä.
f
Instantioija ymmärtää seuraavat viestit:
- LOAD_OK, jäädään odottamaan että käyttäjä antaa dynaamisten rajoitusten
alkuarvoja ja muutosfunktioita sekä painaa START:ia.
- LOAD_FAILED, palataan odottamaan, että käyttäjä antaa uuden LOAD-komennon.
- DYN_PARAMS, kirjoitetaan tämän viestin sisältämät dynaamisten rajoitusten
nimet ikkunaan.
- LAST_VALUES, kirjoitetaan tämän viestin sisältämät dynaamisten rajoitusten
arvot ikkunaan.
- TEXT, näytetään tämän viestin sisältö viesti-ikkunassa.
- CHOOSE, suoritetaan leikkauspisteiden valinta.
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:
- LOAD, kutsutaan kääntäjää antamalla viestin sisältämä tiedostonimi
parametrina.
- START, kutsutaan so_init():a ja käynnistetään animaatio.
- STOP, kutsutaan so_last():a ja pysäytetään animaatio.
- QUIT, kutsutaan cleanup() funktioita, jos osajärjestelmien
pitää vapauttaa joitain resursseja ennen poistumista ja
poistutaan järjestelmästä.
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:
- lukea annettu tiedosto ja luoda sen perusteella kinemaattisesta mallista
globaali tietorakenne, jota ratkaisija tulee
käyttämään.
- lähettää instantioijalle viesti DYN_LIST, joka sisältää listan käyttäjän
määriteltävissä olevista dynaamisista rajoituksista ja arvoalueista
- välittää visualisoijalle linkkien visuaaliset mallit sisältävien tiedostojen
nimet ja linkkien atribuutit linkFiles tietueessa.
- lähettää mahdolliset virheilmoitukset instantioijan ikkunaan
- palauttaa tieto kääntämisen onnistumisesta tai epäonnistumisesta
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:
- kirjoittaa sille parametrina annettuun tietorakenteeseen
kinLinks tiedot uuden ratkaisun
linkeille tehdyistä tranformaatioista
sekä common_objectin ollessa kyseessä sen pituus
- jos ratkaisu oli viimeinen eli malli saavutti lopputilansa, edellä
mainitun lisäksi kutsua so_last():ia
- palauttaa FALSE, jos ratkaisu oli viimeinen, muutoin TRUE
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.
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 |
Notaatio: Laatikot kuvaavat tiloja, nuolet mahdollisia tilasiirtymiä ja
paksut vaakaviivat tapahtuma-toiminto pareja siten, että tapahtuma on
viivan yläpuolella ja toiminto alapuolella.

Kuva 2. Prosessin 1 tilakaavio
(kuva postscript muodossa).
Tapahtumat ja niiden seurauksena tapahtuvat toiminnot.
- MSG_LOAD (1)
Instantioijalta tulee viesti LOAD, joka sisältää ladattavan
tiedoston nimen. Siirrytään kääntämään annettua tiedostoa.
- compiled (2)
Käännös onnistui ja display-listat saatiin tehtyä.
Täten kääntäjä on lähettänyt instantioijalle viestin
DYN_PARAMS, joka sisältää listan dynaamisista rajoituksista. Lähetetään
instantioijalle viesti LOAD_OK.
- failed (3)
Määrittelykieltä sisältävä tiedosto tai joku polygonimalleja sisältävistä
tiedostoista ei löytynyt tai sitä ei ymmärretty.
Kääntäjä tai jälkimmäisessä tapauksessa visualisoija on tulostanut
virheilmoitukset käyttäjälle. Lähetetään
instantioijalle viesti LOAD_FAILED.
- MSG_START (4)
Instantioijalta tulee viesti START. Kutsutaan ratkaisijan so_init():iä,
joka lukee dynaamisten rajoitusten alkuarvot sisältävän viestin
PARAMS_FUNCS instantioijalta. Aletaan näyttää animaatiota.
- MSG_STOP (5)
Instantioijalta tulee viesti STOP. Kutsutaan ratkaisijan so_last():ia,
joka lähettää viimeisen ratkaisun dynaamisten rajoitusten arvot
instantioijalle viestissa LAST_VALUES.
- last solution (6)
Ratkaisija ilmoittaa, että malli saavutti lopputilansa. Ratkaisija on
myös lähetänyt instantioijalle viestin LAST_VALUES, joka sisältää viimeisen
ratkaisun dynaamisten rajoitusten arvot.
- MSG_QUIT (7)
Instantioijalta tulee viesti QUIT. Kutsutaan cleanup-funktioita ja poistutaan ohjelmasta.

Kuva 3. Prosessin 2 tilakaavio
(kuva postscript muodossa).
Tapahtumat ja niiden seurauksena tapahtuvat toiminnot.
- USER_LOAD (1)
Käyttäjä painaa LOAD:ia ja antaa ladattavan tiedoston nimen.
Lähetetään prosessille 1 viesti, joka sisältää annetun tiedoston nimen.
Jäädään odottamaan viestiä kääntämisen onnistumisesta.
- MSG_DYN_PARAMS
Viesti sisältää dynaamisten rajoitusten parametrien nimet sekä alkuarvot
kuten ne on mallin tiedostossa määritelty. Jos käännös ei onnistunut
viesti on tyhjä.
Siirrytään odottamaan lataamisen onnistumista.
- MSG_LOAD_OK (2)
Kääntäminen ja polygonitiedostojen lataus onnistui.
Siirrytään odottamaan käyttäjän komentoa waitStart tilaan.
- MSG_LOAD_FAILED (3)
Uuden mallin kääntäminen tai polygonitiedostojen lataaminen epäonnistui.
Palataan odottamaan uutta LOAD-komentoa.
- USER_START (4)
Käyttäjä painaa START:ia annettuaan dynaamisten rajoitusten arvot ja
muutosfunktiot. Lähetetään ratkaisijalle viesti PARAMS_FUNCS, joka sisältää
dynaamisten rajoitusten arvot. Lähetetään viesti MSG_START ja seurataan
ratkaisijan toimintaa.
- USER_STOP (5)
Käyttäjä painaa STOP:ia. Lähetetään viesti MSG_STOP. Jäädään
tilassa waitLast odottamaan ratkaisijalta saatavia viimeisiä
parametrien arvoja.
- MSG_CHOOSE
Ratkaisijalta tulee viesti, joka vaatii käyttäjää valitsemaan
leikkausfunktion palauttamasta ratkaisupistejoukosta haluamansa
ratkaisupisteen. Valinta tapahtuu tilassa waitSelection.
- MSG_CHOSEN
Käyttäjän valitsema piste lähetetään ratkaisijalle, joka pääsee nyt
jatkamaan ratkaisun laskemista. Siirrytään tilaan waitStop.
- MSG_LAST (6)
Luetaan viesti LAST_VALUES, joka sisältää dynaamisten rajoitusten loppuarvot ja
tulostetaan ne ikkunaan.
- USER_QUIT (7)
Käyttäjä painaa QUIT:ia. Lähetetään viesti MSG_QUIT ja lopetetaan instantioija.
| Sisällysluettelo | Luku 1
| Luku 2 | Luku 3
| Luku 4 | Luku 5
|
KineSimu |
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;
typedef struct {
int id; /* id of link (0 = common object) */
float red, green, blue; /* color of link */
char *filename; /* polygon filename */
} visualModel;
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 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 |
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.
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.
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.
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.
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.
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.
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 |
Kuva visualisoijan modulikaaviosta (postscript).
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:
- GLUT-kirjasto, tämä parsii myös komentoriviltä GLUT:n ymmärtämät argumentit
- ikkunan koko, paikka ja näyttömoodi
- popup-menut
- callback-funktiot, jotka hoitavat käyttäjältä ja ikkunamanagerilta tulevat
tapahtumat sekä "idle":n. Idle on prosessin pääsilmukka, jota kutsutaan
aina kun mitään tapahtumia ei ole käsittelemättä.
Kutsuu OpenGL:n funtioita, joilla alustetaan:
- valonlähteen paikka, tyyppi ja suunta
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).
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:
- vi_display():tä kutsutaan kun GLUT ilmoittaa että ikkuna pitää piirtää uudestaan.
Riippuen prosessin tilasta, se kutsuu renderer modulin eri funktioita:
- NO_MODEL tai LOADED_MODEL: piirretään ohjelman logo
- RENDERED_MODEL: ratkaistaan malli uudessa asennossaan ja piirretään se
- STOPPED_MODEL: piirretään mallin viimeinen ratkaisu uudelleen (mahdollisesti)
uudesta kulmasta visualisoituna
- vi_reshape():iä kutsutaan kun ikkuna luodaan tai ikkunan koko muuttuu. Se
muodostaa uuden projektiomatriisin perustuen ikkunan kokoon.
- vi_mouse():ia kutsutaan kun hiiren napin tila muuttuu.
- vi_mousemotion():ia kutsutaan kun hiirtä liikutetaan nappi painettuna.
Tämä funtio laskee uudet arvot kameran sijainnille ja paikalle
hiiren liikkeiden perusteella.
- vi_visibility():ä kutsutaan kun ikkunan näkyvyys muuttuu. Esimerkiksi kun se
jää kokonaan muiden ikkunoiden taakse. Funktiota ei ole toteutettu vielä.
- vi_menu():a kutsutaan kun päämenussa tehtiin valinta.
- AXES: asetetaan lippu, joka kertoo ovatko koordinaattiakselit näkyvissä
- PAUSE: asetetaan lippu, joka kertoo onko malli pysäytetty visualisoijasta
- RESET: palautetaan kameran sijainti ja asento alkuarvoihin
- QUIT: lopetetaan prosessi
- vi_idle() toimii prosessin 1 pääsilmukkana eli sitä kutsutaan
aina kun mitään tapahtumia ei ole käsittelemättä.
Prosessi 1 voi olla seuraavissa tiloissa:
- NO_MODEL: ei mallia käsiteltävänä
- LOADED_MODEL: malli ladattu ja käännetty onnistuneesti
- RENDERED_MODEL: mallia animoidaan
- STOPPED_MODEL: mallin animaatio on pysäytetty, mutta tallessa on
sen viimeisin piirretty asento
Jokaisessa tilassa mahdollista tapahtumaa kohden, vi_idle() kutsuu vastaavaa
check_...() funktioita, joka tapahtuman sattuessa tekee vaadittavat toiminnot
ja tilasiirtymän.
Prosessin 1 tilakaavio kuvaa vi_idle():n toiminnan.
Tilasiirtymän mahdollistavat tapahtumat ovat:
- LOAD (funktio event_load()) saadaan LOAD-viesti, joka sisältää
ladattavan tiedoston nimen.
Kutsutaan co_compile():a joka kääntää mallin ja vi_makedlists():ä, joka
tekee display listat. Jos em. toiminnot onnistuivat siirrytään tilaan
LOADED_MODEL.
- START (funktio event_stop()) saadaan START-viesti. Kutsutaan so_init():ä,
joka lukee instantioijalta tulevan viestin, joka
sisältää dynaamisten rajoitusten alkuarvot ja muutosfunktiot.
Siirrytään tilaan RENDERED_MODEL.
- STOP (funktio event_stop()) saadaan STOP-viesti. Kutsutaan so_last():a,
joka lähettää instantioijalle viestin, joka sisältää dynaamisten
rajoitusten loppuarvot.
Siirrytään tilaan STOPPED_MODEL.
- QUIT (funktio event_quit()) saadaan QUIT-viesti. Kutsutaan
cleanup() funktiota joka lopettaa prosessin siististi.
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.
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ä.
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 |
Kuva kääntäjän modulikaaviosta (postscript).
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.
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.
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.
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.
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 |
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.
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.
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:
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:
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.
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:
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:
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:
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 |
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:
- "ACIS Application Procedural Interface"
- polygModel
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:
- defModel1, defModel2, ...
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 |
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:
- "ACIS Facetter Husk"
- polygSave
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.
Simulaattorin kahden prosessin, instantioijan ja visualisoijan,
välinen tiedonsiirto hoidetaan viestien välityksellä.
Unix tarjoaa viestien välitykseen systeemikutsut "msgget",
"msgsend", "msgrcv" ja "msgctl".
KineMessage on kirjasto, joka toteuttaa viestin välityksen simulaattorin
kahden prosessien välillä
käyttämällä Unix:in systeemikutsuja.
Kirjasto sisältää funktiot:
- void kineSend(int pid, int key, char *messagetext)
lähettää prosessille pid viestin key, jossa on data
messagetext.
Lopettaa ohjelman, jos lähetys epäonnistui.
- int kineReceive(int pid, int key, char *returntext)
kopioi vastaanottajalle pid lähetetyn viestin key dataosan argumentin
returntext osoitteeseen.
Palauttaa kopioitujen tavujen lukumäärän, tai -1 jos vastaanotto
epäonnistui.
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.
- LOAD:
char filename[MSG_SIZE]
Merkkijonossa on valitun tiedoston nimi.
- TEXT:
char text[MSG_SIZE]
Merkkijonossa on viesti-ikkunaan tulostettava teksti.
- CHOOSE:
char points[MSG_SIZE]
Merkkijonossa ovat pisteiden koordinaatit float Mark1_x, float Mark1_y, float Mark1_z, float Mark2_x, ... välilyönnillä erotettuina.
- CHOSEN:
char selected[MSG_SIZE]
Merkkijonossa on luku int index, joka tarkoittaa valitun pisteen
indeksiä viestin CHOOSE järjestyksessä alkaen ykkösestä.
- MODE:
char mode_name[MSG_SIZE]
Merkkijonossa on valitun moodin nimi.
- LOAD_OK:
NULL
- START:
NULL
- STOP:
NULL
- QUIT:
NULL
- LOAD_FAILED:
NULL
- PARAMS_FUNCS:
char params_funcs[MSG_SIZE]
Merkkijonossa ovat tiedot float param , char *arg ja char *func
välilyönnillä erotettuina. param-func -parit erotetaan
toisistaan myös välilyönnillä.
Tässä param on parametrin arvo, arg on funktion
argumentit ja func on
funktion nimi. param laitetaan merkkijonoon
esim. kirjastofunktiolla
"sprintf" ja otetaan merkkijonosta funktiolla "atof".
- LAST_VALUES:
char params[MSG_SIZE]
Merkkijono koostuu välilyönnillä toisistaan erotetuista
luvuista float param,
jotka ilmoittavat kyseisen parametrin arvon.
Lukujen tulee olla samassa järjestyksessä kuin yllä.
- DYN_PARAMS:
char names[MSG_SIZE]
Merkkijono koostuu välilyönnillä toisistaan erotetuista
parametrien nimistä.
Nimien tulee olla samassa järjestyksessä kuin yllä.
| Sisällysluettelo | Luku 1
| Luku 2 | Luku 3
| Luku 4 | Luku 5
|
KineSimu |
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:
- "Reload" lataa aiemmin valitun, ikkunan otsikossa
näkyvän, tiedoston.
- "Load" käynnistää tiedostonselausikkunan, josta
valitaan hiirellä kaksoisnäpäyksellä tai yksinkertaisella
valinnalla ja OK-napilla
ladattava tiedosto. Toiminnon voi peruuttaa painamalla
QUIT-napista tai tappamalla selausikkunan.
- "Quit" esittää varmistusdialogin, johon
valitsemalla "Ok" lopetetaan koko simulaattori.
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.
- "Start" käynnistää animoinnin niillä parametrien
arvoilla ja funktioilla, jotka ikkunassa on valittu.
- "Stop" keskeyttää animoinnin. Parametrilistaan
ilmestyvät tällöin viimeisimmät käytetyt arvot.
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:
- Parametrin järjestysnumero ja nimi.
Nimi on käyttäjän antama dynaamisen rajoituksen parametrin nimi.
- Parametrin syöttöfunktion nimi.
Tämä voidaan asettaa "Funcs"-valikosta, kun parametri on valittu.
- Parametrin syöttöfunktion argumentti.
Tämä voidaan antaa kenttään "Parameter Func Arg:", kun parametri on valittu.
Useampi argumentti voidaan antaa aaltosuluissa.
- Parametrin arvo.
Tämän asetusarvo voidaan antaa kenttään "Parameter Set Value:",
kun parametri on valittu.
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 |
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.
Popup-menut ilmestyvät näkyviin painamalla hiiren oikeanpuolimmaista nappia
visualisoijan ikkunassa.
Kuva 5. Popup menu.
Toiminnot:
- Pause, pysäyttää animaation hetkellisesti
- Toggle axes laittaa koordinaattiakselit päälle/pois
- Init camera laittaa kameran alkuasentoonsa
- Polygon mode valitsee täytetyt polygonit/rautalankamallin
- Quit, poistuu visualisoijasta
Hiirellä voi pyörittää ja zoomata mallia pitämällä vasemman puoleista tai
keskimmäistä nappia pohjassa ja liikuttamalla hiirtä.
Toiminnot vasen nappi pohjassa:
- ylös, suurentaa mallia
- alas, pienentää mallia
- vasemmalle/oikealle, pyörittää mallia globaalin koordinaatiston
z-akselin ympäri
Toiminnot keskimmäinen nappi pohjassa:
- ylös/alas, pyörittää mallia globaalin koordinaatiston x-akselin ympäri
- vasemmalle/oikealle, pyörittää mallia globaalin koordinaatiston
y-akselin ympäri
Kuva 6. Visualisoijan ikkuna.
| Sisällysluettelo | Luku 1
| Luku 2 | Luku 3
| Luku 4 | Luku 5
|
KineSimu |
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
- common: visuaalinen ulkoasu on common-object
- loop: visuaalinen ulkoasu on common-object, missä viimeinen markeri
on yhdistetty ensimmäiseen
- blank: linkki on näkymätön
- <n>: polygonimalli
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:
- coincident: Markerit ovat samassa paikassa.
- inline: marker-1 on marker-2:en z-akselilla.
- inplane: marker-1 on marker-2:en xy-tasolla.
- displacement: marker-1:en ja marker-2:en välinen etäisyys on x (parametri).
- parallel-z: marker-1:en ja marker-2:en z-akselit ovat samansuuntaiset.
- perpendicular-z: marker-1:en ja marker-2:en z-akselit ovat kohtisuorassa.
- co-oriented: marker-1:en ja marker-2:en z-akselit ovat samansuuntaiset
sekä marker-1:en x-akselin kulma marker-2:en x-akseliin on alpha (parametri).
- screw: marker-1:en ja marker-2:en z-akselit ovat samansuuntaiset sekä
marker-1:en x-akselin kulma marker-2:en x-akseliin on suoraan verrannollinen
markerien väliseen etäisyyteen. Verrannollisuuskerroin on delta (parametri).
<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.
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 |
- Markkeri eli marker
Piste, jolla on oma koordinaatisto. Koordinaatisto
määrittää pisteen asennon. Markkerin koordinaatisto määrää myös
geomiin mahdollisesti kuuluvien muiden pisteiden sijainnit ja asemat,
koska tässä käsitellyt geomit ovat kaikki jäykkiä.
- Kiinnitetty eli grounded markkeri
Kiinnitetyn markkerin sijainti globaalissa koordinaatistossa tunnetaan.
- Rajoitus eli constraint
Rajoitus on relaatio kahden markkerin välillä. Sen täyttäminen
vaatii toisen markkerin, ja samalla sen sisältävän geomin, siirtämistä ja
pyörittämistä. Rajoitus voi koskea esimerkiksi markkereiden etäisyyttä tai
kulmaa. Rajoituksella voi tyypin lisäksi olla myös parametri, kuten
kulman tai
etäisyyden numeroarvo. Tyypeillä kulma ja etäisyys tietenkin täytyykin olla
parametri, eiväthän ne muuten mitään rajoita. Tyyppejä ilman parametreja
voisivat olla vaikka erikoistapaukset samansuuntaisuus ja yhtenevyys.
- Dynaaminen rajoitus eli driving input
Dynaaminen rajoitus on rajoitus, jonka parametria muuttamalla
saadaan mekanismi eri tiloihin. Näitä tiloja peräkkäin näyttämällä saadaan
animaatio mekanismin toiminnasta.
- Staattinen rajoitus tai rajoitus eli constraint
Staattisen rajoituksen parametreja ei muuteta simuloinnin aikana.
- Geomi eli geom
Geomilla tarkoitetaan jotakin geometrista entiteettiä. Esimerkiksi jana,
ympyrä ja yleinen
jäykkä kappale ovat geomeja. Janaan kuuluu kaksi markkeria,
ympyrään yksi markkeri ja vakio säde.
Yleiseen jäykkään kappaleeseen voi kuulua yhdestä n:ään markkeria,
joiden sijainnit toistensa suhteen tunnetaan.
Tässä työssä yleiset jäykät kappaleet riittävät.
- Makrogeomi eli macrogeom
Makrogeomi koostuu kahdesta tai useammasta toistensa suhteen kiinnitetystä
geomista.
- Linkki eli link
Linkki on sama kuin geomi.
- Lokaali koordinaatisto eli local coordinate system
Jokaisella markkerilla on oma lokaali koordinaatisto.
Alussa myös geomeilla on lokaali koordinaatisto, mutta sitä ei tarvita
enää ratkaisuvaiheessa.
- Liitos eli joint
Liitos on yhden tai useamman rajoituksen määräämä kahden markkerin välinen
relaatio, joka kertoo kuinka markkerit voivat toistensa suhteen liikkua.
Samalla se kertoo, kuinka ko. markkerit sisältävät geomit voivat
toistensa suhteen liikkua.
Jos esimerkiksi halutaan mallittaa ihmisen kyynärnivelen tyyppistä
liitosta
kolmessa ulottuvuudessa, tarvitaan kaksi rajoitusta. Toinen rajoittaa
olkavarren ja kyynärvarren tiettyyn tasoon ja toinen niiden päät samaan
pisteeseen. Pelkästään samaan pisteeseen rajoittamalla luotaisiin pallonivel,
josta esimerkkinä olkanivel. Liitos voi tietenkin sallia myös siirtoa tai
sekä siirtoa että pyörimistä, kuten putken sisällä oleva lieriö, eli
nk. sylinteriliitos.
- Vapausaste eli degree of freedom
Vapausasteilla kuvataan geomien liikkumavapautta. Niitä on käytetty
myöskin markkerien liikkumavapauden määrittelyyn.
Vapausaste määritellään siten, että geomin jokaista vapausastetta kohti
tarvitaan yksi reaaliarvoinen parametri, jotta geomi saataisiin
kiinnitettyä.Tasossa vapaa markkeri voi liikkua vapaasti
kaksiulotteisessa avaruudessa eli ko. tasossa ja pyöriä tasoa
vastaan kohtisuoran akselin ympäri. Niinpä sillä on kaksi siirto- ja yksi
pyörimisvapausaste. Avaruudessa vapaalla markkerilla on kolme siirto- ja
kolme pyörimisvapausastetta. Jos markkerilla on esimerkiksi yksi
siirtovapausaste tasossa, se voi olla minkä tahansa tason suoran suuntainen.
Samoin pyörimisvapausaste avaruudessa voi olla minkä tahansa avaruuden
suoran ympäri.
Englanniksi translational degree of freedom (TDOF) ja rotational degree of
freedom (RDOF).
- Geometrinen malli eli geometric model
Geometrinen malli käsittää geomit ja niiden väliset rajoitukset.
Kiinnitetyt geomit ovat keino sitoa malli globaaliin koordinaatistoon.
- Kinemaattinen malli eli kinematic model
Kinemaattinen malli on geometrinen malli, jossa jonkin staattisen
rajoituksen parametria muuttamalla saadaan aikaan liikettä. Toisin
sanoen jostain tai joistakin staattisista rajoituksista tehdään
dynaamisia.
- Visuaalinen malli eli visual model
Visuaalisten mallien avulla määrätään geomien ulkoasu. Esimerkiksi jana
voitaisiin näyttää janan mittaisena lieriönä tai ihan minä tahansa
tarkoituksenmukaisena muotona.
- Reseptikirja eli plan fragment table
Reseptikirja eli plan fragment table kertoo kuinka jokin tietty rajoitus
saadaan täytettyä. Kulloinkin käytettävä resepti eli plan fragment määräytyy
täytettävän rajoituksen tyypin ja siirrettävän geomin vapausasteiden funktiona.
- Toiminta-analyysi eli action analysis
Toiminta-analyysi eli action analysis määrää, mitä siirtoja ja translaatioita
tarvitaan rajoituksen täyttämiseksi. Toiminta-analyysi toteutetaan
reseptikirjassa.
- Lokus eli locus
Lokus eli locus on markkerin sallittujen sijaintien muodostama aliavaruus.
Jos esimerkiksi tasossa olevan janan toisen päätepisteen sijainti on
määrätty, niin toisen pisteen lokus on ympyrä.
- Lokuskirja eli locustable
Lokuskirja eli locustable sisältää kullakin mahdollisella tavalla
rajoitettujen geomien jäsenmarkkerien lokukset. Esimerkiksi jos tasossa
sijaitsevalla janalla on yksi siirtovapausaste, niin sen jäsenmarkkerien
lokukset ovat vapausasteensuuntaisia suoria.
- Lokusleikkauskirja eli locus intersection
Lokusleikkauskirja eli locus intersection table sisältää menetelmät
erityyppisten lokusten välisten leikkausten laskemiseksi.
- Lokusanalyysi eli locus analysis
Lokusanalyysi eli locus analysis tarkoittaa lokuksien ja niiden leikkausten
määrittämistä markkerien mahdollisten sijaintien löytämiseksi. Esimerkiksi
kahden toisestä päästään kiinnitetyn janan vapaiden pisteiden yhdistämiseksi
täytyy laskea niiden ympyränmuotoisten lokuksien leikkauspisteet.
| Sisällysluettelo | Luku 1
| Luku 2 | Luku 3
| Luku 4 | Luku 5
|
KineSimu |