Animasjon
JOGL
Grafikk
Morten Haraldsen / Student 2004
Å tegne:>Robot

Robot

Hva
robot_shot_01

Målet med denne oppgaven er å lage en animasjon av en robot som kan styres manuelt ved hjelp av GUI eller ved hjelp av en enkel styrefil.

Etter noen dager med skriving av direkte kode for tegning av flater og sylindere viste dette seg svært tungt å få laget en estetisk pen robot. Dermed oppsto idèen om å kunne laste inn en modell modellert i et 3D program. Dette gir mye strre fleksibilitet med tanke p oppdatering av modeller, og gir ogs muligheten for angi en del materialegenskaper og lys instillinger, slik at dette ikke br gjres manuelt. Neste steg er tegne opp robotens del-modeller i riktig posisjon, for s animere roboten. Roboten kan styres enten manuelt eller via en styrefil, spesifisert i XML.

Valget falt på JOGL som OpenGL implementsjon, da den er Java basert, et språk jeg føler jeg mestrer godt. På denne måten kan jeg fokusere tiden min på å jobbe med OpenGL kode, og ikke mtte lre seg et nytt programmeringssprk i samme omgang. Prosjektet startet med å lage et enkelt rammeverk for programmet. Rammeverket bestr av et vindu for OpenGL og et enkelt setup panel der man kan se informasjon om skjermkort og maskinen og ogs styre antall frames per sekund (fps) man vil vise. Rammverket ble enkelt tilpasse, og man trengte n bare forandre rutinene for opptegning for presentere grafikk.

Etter kort tid innså jeg at å lage en robot som ser ut som en industrirobot hard-kodet via OpenGL kommandoer ville være svært tidkrevende og lite fleksibelt for oppdateringer. Særlig for oppdatering av indiviuelle deler av roboten. Dette ville medføre at f.eks bytting av forskjellige verktøy på roboten ville bli vanskelig hvis slik funksjonalitet ville være ønskelig senere. Dette medførte at jeg begynte å se etter hvordan jeg kunne tegne ferdige modeller lastet inn fra fil. OpenGL kun er et API for tegning av 2D og 3D, og har ikke støtte for noe slik funksjonalitet så derfor måtte jeg skrive kode for dette selv.

Konvertering og lasting av modeller

Da det var klart at jeg ville bruke tegnede 3D modeller begynte jeg se etter modeller av roboten. Roboten som str ved IR avdelingen i Sarpsborg er fra 92-93, s denne var det ikke s mye data og finne om p ABB sine hjemmesider. Valget falt derfor p en nyere og mer sofistikert robot. Denne modellen var det allerede laget CAD modeller av (produksjonstegninger). Disse tegningene var tilgjengelig i en mengde formater og mange av verktyene for behandlig av disse er desverre ekstremt bde dyre og avanserte. Etter ha testet omtrent de shareware versjonene som finnes av CAD programvare, fant jeg endelig programmet "Rhinoceros" som kunne laste en CAD modell i fra formatet *.igs. Dette programmet kunne ogs eksportere geometrien som en 3D Studio MAX eller LightWave fil.

Likevel var det mer konvertering som mtte til, da 3D Studio MAX og Lightwave har relativt komplekse format p sine filer ville jeg ndig mtte parse dette formatet direkte. Neste oppgave var da finne et egnet filformat for innlesing i programmet, da flesteparten av disse formatene (3D Studio Max og Lightwave) er vanskelige lese inn, og er ofte properitre eller uten tilgjengelig dokumentasjon. Et standard ASCII filformat ville vre ideelt for innlesing og parsing via Java, og i min sken fant jeg etter en stund programmet MilkShape. Programmet sttter importering av mange kjente filformat og kan eksportere til et relativt enkelt ASCII format som dessuten var dokumentert godt. Milkshape er et enkelt modelleringsprogram opprinnelig utviklet for kunne behandle modeller fra spillet Half-Life. Programmet har etter hvert ftt sttte for mange flere formater og foretrekkes i dag av svrt mange p.g.a. lav pris og at det er enkelt i bruk. Milkshape har som de fleste andre 3D programmer støtte for å sette materialegenskaper og lysegenskaper, og har også støtte for teksturer. På denne måten kan man gjøre seg ferdig med modellen i 3D programmet , og så bruke geometri, materialegenskaper og teksturnavn fra ASCII fila for tegning av modellen i OpenGL senere. Det skal nevnes at modellene brukt er fra byggetegninger og derfor er svrt detaljerte og relativt tunge rendre i OpenGL uten et skikkelig grafikk-kort.

milkshape_shot
Milkshape etter ha lastet inn en modell av en av delene av roboten.

Etter ha forsttt formatet var det finne en grei mte representere modellene internt som objekter i programmet. En scene bestr av en eller flere modeller, som igjen har en eller flere mesh'er, som igjen kan ha et materiale, som igjen kan bestr av overflateverdier for refleksjon, farge osv og evt en tekstur. Det viser seg at det blir et lite hierarki av objekter. For mest mulig oversiktelig kunne bygge opp en scene ble det derfor utviklet en klasser som representerer disse.

scene_tree
Oversikt over hvordan en scene er bygget opp i programmet.

Videre ble det laget en egen Texture klasse. Jeg valgte PNG som format for teksturer. Texture klassen kan bygges ut til sttte f.eks BMP og JPG, men jeg har ikke tatt meg tid til dette. Da det er godt mulig at flere modeller bruker de samme texturene ble det implementert en teksturliste slik at man kan dele tilgang til en tekstur. Dette gjr at man unngr lasting av en tekstur flere ganger, noe som igjen frer til raskere oppstart og sparer minne.

Merk: Teksturene ligger under 'program/build/data/textures'. Modellene ligger under 'program/build/data/models'.

Tegning av roboten

Nr geometrien for delene av roboten er lest inn er neste steg tegne opp modellen p skjermen. Siden det er rimelig komplekse modeller som skal tegnes blir det mange triangler tegne. tegne alt p via kode hver gang eller legge det i en "display list", skal visstnok ikke ha noen betydning for ytelsen p moderne grafikk-kort. Likevel merket jeg i JOGL en 30-40% ytelseskning ved bruke display lister. Dette kan komme av at display listene blir bufret og tegnet via native kode i JOGl, og man slipper bruke Java's minnehndtering og iterasjonsmetoder ved opptegning.

Nr programmet starter opp laster det inn alle modeller og lager en liste over hvilke teksturer som m lastes inn. Nr alle modellene er lastet inn, er neste steg laste inn alle ndvendige teksturer og gi referansene til disse til hvert Mesh objekt som bruker den gitte teksturen. Neste steg er lage display listeene for hver modell som er nevnt i avsnittet over. Scene objektet holder oversikt over hvilken ID modellen har i display lista internt i OpenGL og man kan hente ut denne nr man vil tegne opp en modell i OpenGL.

I kode vil dette se slik ut:

// Load models
String modelPath = "data/models/";
String[] modelFiles = new String[]
{
	"foot.txt",
	"rotation.txt",
	"lower_arm.txt"
	"elbow.txt",
	"upper_arm.txt",
	"floor.txt",
	"mount.txt"
};

// Init scene
this.scene = new Scene();
for (int i = 0; i < modelFiles.length; i++)
{
	this.scene.addModel(new MilkShapeModel(modelPath + modelFiles[i], modelFiles[i]));
}

N nr alle modellene er lastet inn (ogs teksturer), s kan vi gjre klar scenen til rendering. Dette gjres ved kalle "prepareScene" i Scene klassen fra init i OpenGL:

public void init (GLDrawable drawable)
{
	// Save references
	this.gl = drawable.getGL();
	this.glu = drawable.getGLU();
	this.glDrawable = drawable;

	// Prepare scene
	this.scene.prepareScene(gl, glu);

Dette gjr at displaylistene blir generert og OpenGL id-ene til listene blir lagret i Scene objektet slik at vi kan finne tilbake til riktig liste for en modell nr vi skal tegne opp modellen. Opptegningen av roboten utfres p denne mten:

public void display(GLDrawable drawable)
{
	// Clear scene
	gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

	// Reset view
	gl.glLoadIdentity();

	// Update view if user has rotated or zoomed the scene
  	gl.glTranslatef(0.0f, -12.0f, zoom);
  	gl.glRotated(xrot, 1.0, 0.0, 0.0);
	gl.glRotated(yrot, 0.0, 1.0, 0.0);

	// Draw models

	// Draw robot mount
	gl.glPushMatrix();
  	gl.glTranslatef(-7.2f, 0f, -4.6f);
  	gl.glScalef(0.3f, 0.3f, 0.4f);
	drawModel(scene.getDisplayListIndex("mount.txt"), gl);

	// Foot
	gl.glPopMatrix();
	gl.glPushMatrix();
	drawModel(scene.getDisplayListIndex("foot.txt"), gl);

	// Rotation model
	gl.glTranslatef(0.0f, 2.0f, 0.0f);
	gl.glRotatef(robotStatus.getAxisAngle(0), 0.0f, 1.0f, 0.0f);
	drawModel(scene.getDisplayListIndex("rotation.txt"), gl);

	// Lower arm
	gl.glTranslatef(3.3f, 5.8f, 1.35f);
	gl.glRotatef(robotStatus.getAxisAngle(1), 0.0f, 0.0f, 1.0f);
	drawModel(scene.getDisplayListIndex("lower_arm.txt"), gl);

	...
  

Kontroll av roboten

Roboten kan kontrolleres p to mter. Enten helt manuelt via GUI, eller den kan forhndsprogrammeres til utfre en serie bevegelser. Manuell kontroll av roboten skulle vre ganske intuitivt, s jeg konsentrer meg om automatisk kjring. Dette utfres ved at roboten leser en XML fil med spesifikasjoner for hvilke bevegelser som skal utfres ved forskjellige tidspunkt. Alle ledd kan beveges uavhengig av hverandre til samme tid, med forskjellige hastigheter hvis det skulle vre nskelig. Filen har et meget enkelt format, og forklares best med et eksempel:

<?xml version="1.0" encoding="UTF-8"?>
<robotprogram axisCount="4">
    <move time="2000">
        <axis id="0" abs="0">-40.0</axis>
        <axis id="1" abs="0">-80.0</axis>
        <axis id="2" abs="0">80.0</axis>
        <axis id="3" abs="0">180.0,-180.0</axis>
    </move>
    <move time="2000">
        <axis id="0" abs="0">40.0</axis>
        <axis id="1" abs="0">80.0</axis>
        <axis id="2" abs="0">-80.0</axis>
        <axis id="3" abs="0">-180.0,180.0</axis>
    </move>
</robotprogram>

Filen begynner med spesifisere hvor mange akser roboten har (axisCount="4"). Deretter kommer robotens frste sammensatte bevegelse: Akse 0 skal roteres -40 grader, akse 1 skal rotere -80 grader osv. Alt dette skal utfres p tiden som er angitt med attributtet "time" i "move" elementet, i dette tilfellet 2000 millisekunder. Attributtet "abs" angir om det er relative eller absolutte posisjoner for aksene. Forelpig er bare relative posisjoner implementert.

Nr roboten skal utfre et slikt "program" laster den frst inn hele fila i minnet og deler opp bevegelsen i sm fragmenter som legges i et multidimensjonalt array. Nr programmet s er ferdig bearbeidet, kan det enkelt utfres med en enkel program trd, da alle aksebevegelser allerede er kalkulert. Desverre finnes det ikke noen editor for lage fila automatisk via f.eks. en makro opptaker. Dette hper jeg f implementert i en fremtidig versjon.

Konklusjon og videre arbeid

Kravet til prosjektet som ble satt ved kursets start, burde vre oppfylt med dette. Likevel er det fortsatt rom for forbedringer og utvidelser. se en robot utfre "ekte" oppgaver er selvsagt fristende, men jeg har ikke latt roboten f noen spesifikk oppgave, da f.eks. flytting av gjenstander ville mtte hardkodes sammen med bevegelsen p roboten. Dette kun vrt lst med implementasjon av fysiske lover, slik at objekter som kasser, esker osv. vil falle ned p gulvet, og at man kan dytte ting unna hvis de ikke er for tunge og/eller har for stor friksjon. Dette er en stor oppgave i seg selv, og jeg har ikke hatt tid til mer enn s vidt lage et "skall" for hvordan slik funksjonalitet kan implementeres. Prosjektet har blitt relativt solid, og burde vre en grei lsning bygge videre p. Det har blitt en del kode (ca. 3000 linjer), men koden er godt kommentert og skulle vre mulig orientere seg i. Mange av klassene kan brukes til annet enn robot animasjoner. Klassene er oppdelt i "packages" etter hvilken funksjonalitet de har, mye likt Java's eget klasse bibliotek.

Videre vil det som allerede nevnt vre nskelig lage en makro opptaker som kunne ta opp/redigere alle manuelle bevegelser utfrt med roboten, slik at de kan lagres og spilles av senere som et vanlig XML "program". Siden koden for innlasting av nye modeller n er spass enkel, burde det kunne g an bygge et noenlunde troverdig milj der en eller flere roboter arbeider.

[1] [2] [3] [4] [5] [6] [7] [8] [9]

Gode hjelpere:

  • Mats Lindh

Kode

Kildekode, pakket: allsourcecode.zip

Datafiler, pakket: data.zip

Javadoc: javadoc/

Referanser
  1. JOGLSunkenai.com/projects/jogl/pages/Home14-09-2009
  1. Modeling tools for designersRhinoceroswww.rhino3d.com/14-04-2010
  1. MilkShape 3Dtruebones.comchumbalum.swissquake.ch/ms3d/index.html14-04-2010
  1. XML Pull Parserwww.extreme.indiana.edu/xgws/xsoap/xpp/14-04-2010
  1. Gage Timerjava.dnsalias.com/14-04-2010
  1. Latest 'NEHE' NewsNEHE, NeonHelium ProductionsOpenGL-tutorials.nehe.gamedev.net/14-03-2009
  1. ABB Roboticswww.abb.com/robotics14-04-2010
  1. The OpenGL Programming Guide, 6 editionDave Schreiner, Mason Woo,Jackie Neider,Tom Davies2007Addison-Wesley Professional0321481003www.opengl.org/documentation/red_book/14-03-2010
  1. The OpenGL Reference Manual 4 editionDave Schreiner2004Addison-Wesley Professional032117383Xwww.opengl.org/documentation/red_book/14-03-2010
Vedlikehold
Skrevet juni 2004, Morten Haraldsen
Tilpassing av layout juni 2004, Børre Stenseth
Å tegne:>Robot
til toppen