VisClient/org/hfbk/vis/visnode/VisUeberwach.java

Go to the documentation of this file.
00001 package org.hfbk.vis.visnode;
00002 
00003 import java.util.ArrayList;
00004 import java.util.Date;
00005 import java.util.HashMap;
00006 import java.util.List;
00007 
00008 import org.dronus.gl.GLBoxRenderer;
00009 import org.dronus.gl.GLSphereRenderer;
00010 import org.dronus.gl.GLFont;
00011 import org.dronus.gl.GLUtil;
00012 import org.dronus.graph.Node;
00013 import org.hfbk.vis.Prefs;
00014 import org.lwjgl.opengl.GL11;
00015 import org.lwjgl.util.vector.Vector3f;
00016 
00058 public class VisUeberwach extends VisNode {
00059 
00061         final float DVARIANCE_DT=10f; // units/s
00063         final float NEW_COST=5f;
00065         final float EXIT_VARIANCE=100;
00066         
00067 
00068         
00073         class Item{
00075                 Vector3f pos;
00077                 Vector3f dpos=new Vector3f();
00078         }
00079         
00085         class VisTrack extends VisNode{
00086                 
00087                 int id;
00088                 
00089                 final int PAST_STATES=10;
00090                 int index; //index to this items ring buffer
00091                 
00093                 Item[] past=new Item[PAST_STATES];
00094                 
00096                 Item current;
00097                 
00100                 float variance;
00101                 
00102                 
00103                 public VisTrack() {
00104                         super(null, new Vector3f());
00105                         id=maxTrackId++;
00106                         Item tp=new Item();
00107                         current=past[0]=tp;     
00108                         radius=10000;
00109                 }
00110                 
00114                 int push(){
00115                         Item last=getOld(0);
00116                         Item tp=new Item();
00117                         tp.pos=new Vector3f(last.pos); tp.dpos=new Vector3f(last.dpos);
00118                         
00119                         index++;
00120                         index%=PAST_STATES;
00121                         past[index]=tp;
00122                         current=tp;
00123                         
00124                         return index;                   
00125                 }
00126                 
00135                 protected void renderSelf() {
00136                         float dt=getRoot().client.dt;                   
00137                                 
00138                         Item tp=past[index];
00139                         Vector3f d=new Vector3f(tp.dpos);
00140                         d.scale(dt);
00141                         Vector3f.add(tp.pos, d, tp.pos);
00142                         variance+=DVARIANCE_DT*dt;
00143                         
00144                         position.set(current.pos);
00145                         
00146                         
00147                         float c=id*523.724325f;  //calculate some unique color by the id
00148                         GL11.glColor4f(1-c%1,(c*3)%1,c%1,1/(1+variance/100)); //alpha is controlled by variance   
00149                         GLSphereRenderer.renderSphere(variance/5);
00150                         
00151                         
00152                         GL11.glTranslatef(-4,2,0);
00153                         GLUtil.billboardCylinder();
00154                         GL11.glColor3f(1,1,1);
00155                         GLFont.getDefault().render();
00156                         GLFont.getDefault().print(getDatasheet());
00157                         GL11.glDisable(GL11.GL_TEXTURE_2D);
00158                         
00159                         
00160                         
00161                         
00162                         if(variance>EXIT_VARIANCE)
00163                                 parent.remove(this);
00164                 }
00165                 
00167                 Item getOld(int lookback){
00168                         int i=(index-lookback)%10;
00169                         return past[i];
00170                 }
00171 
00172                 long created=System.currentTimeMillis();
00173                 long lastseen=created;
00174                 String getDatasheet(){
00175                         return  
00176                         "Known since: "+(new Date(created))+"\n"+
00177                         "Last spotted: "+(new Date(lastseen))+"\n"+
00178                         "ID:"+hashCode()+"\n";
00179                 }
00180                 
00181                 protected void transform() {
00182                         super.transform();
00183                         GL11.glRotatef(90, 0, 1, 0);
00184                 }
00185         }
00186         
00193         interface Sensor{
00195                 abstract float    getCost(VisTrack track);
00198                 abstract void update(VisTrack track);
00199         }
00200         
00201         
00202         int maxTrackId=0;
00203         
00204         
00205         public VisUeberwach(Node node, Vector3f position) {
00206                 super(node, position);
00207                 radius=Float.MAX_VALUE;
00208         }
00209         
00211         static Vector3f lerp(Vector3f a, Vector3f b, float t){
00212                 a=new Vector3f(a); b=new Vector3f(b);
00213                 a.scale(1-t); b.scale(t);
00214                 Vector3f result=new Vector3f();
00215                 Vector3f.add(a,b, result);
00216                 return result;
00217         } 
00218         
00229         void trackOne(Sensor s){
00230                 List<VisTrack> tracks=new ArrayList<VisTrack>();
00231                 
00232                 for (VisNode n: children)
00233                         if (n instanceof VisTrack)
00234                                 tracks.add((VisTrack)n);
00235                 
00236                 int nt=tracks.size();
00237                 
00238                 float[] costs=new float[nt+1];  //one more item for possibly new one
00239                 for (int t=0; t<nt; t++)
00240                         costs[t]=s.getCost(tracks.get(t))/tracks.get(t).variance;
00241                 
00242                 costs[nt]=NEW_COST;     //possible new item propability
00243                 
00244                 //find most likely Track to acommodate this sensors data
00245                 // (nearest neighbour)
00246                 int minT=-1;
00247                 float minCost=Float.MAX_VALUE;
00248                 for (int t=0; t<=nt; t++)
00249                         if (costs[t]<minCost){
00250                                 minCost=costs[t];
00251                                 minT=t;
00252                         }
00253                 
00254                 VisTrack t;
00255                 if (minT==nt){  //most likely we got a new thing
00256                         t=new VisTrack();
00257                         add(t);
00258                 }       
00259                 else t=tracks.get(minT);
00260                 
00261                 s.update(t); //update Track with Sensors data.
00262         }
00263 
00264         
00265         class VisCamera extends VisNode {
00266                 float heading, pitch; 
00267                 
00268                 public VisCamera(Vector3f pos, float heading, float pitch,  String ip) {
00269                         super(null, pos);
00270                         this.heading=heading;
00271                         this.pitch=pitch;
00272                         cameras.put(ip,this);
00273                 }
00274                 
00275                 protected void transform() {
00276                         super.transform();
00277                         GL11.glRotatef(heading, 0,1,0);
00278                         GL11.glRotatef(pitch,   1,0,0);                 
00279                 }
00280                 
00281                 protected void renderSelf() {
00282                         GL11.glDisable(GL11.GL_TEXTURE_2D);
00283                         GL11.glColor4f(.3f,.5f,1,.5f);
00284                         GLBoxRenderer.renderBox(3,3,1);
00285                         GL11.glBegin(GL11.GL_LINES);
00286                         GL11.glVertex3f(0,0,0); GL11.glVertex3f(-7,-5,50);
00287                         GL11.glVertex3f(0,0,0); GL11.glVertex3f( 7,-5,50);
00288                         GL11.glVertex3f(0,0,0); GL11.glVertex3f( 7, 5,50);
00289                         GL11.glVertex3f(0,0,0); GL11.glVertex3f(-7, 5,50);
00290                         GL11.glEnd();
00291                 }
00292         }
00293         
00298         class VisSonar extends VisNode implements Sensor{
00299                 
00300                 float distance, speed;
00301                 
00302                 float maxdistance; //for static filtering (walls etc.)
00303                 
00304                 float timer;
00305                 final float TIMEOUT=1; //seconds
00306                 final float MAX_FUZZ=5; //units
00307                 final float WEIGHT_DIST=1, WEIGHT_SPEED=0;
00308                 
00309                 float heading, pitch; 
00310                 
00311                 public VisSonar(Vector3f pos, float heading, float pitch) {
00312                         super(null, pos);
00313                         this.heading=heading;
00314                         this.pitch=pitch;
00315                         radius=10000;
00316                 }
00317                 
00321                 void receive(float distance, float speed){
00322                         //only accept non-static values
00323                         maxdistance=Math.max(maxdistance, distance);
00324                         if (distance>maxdistance-MAX_FUZZ) return;                              
00325                         
00326                         this.distance=distance; this.speed=speed;                                               
00327                         trackOne(this);
00328                         timer=0;
00329                 }
00330                 
00331                 protected void transform() {
00332                         super.transform();
00333                         GL11.glRotatef(heading, 0,1,0);
00334                         GL11.glRotatef(pitch,   1,0,0);                 
00335                 }
00336                 
00339                 void renderSelf() {
00340                         
00341                         timer+=getRoot().client.dt;
00342                         if (timer>TIMEOUT){
00343                                 distance=speed=0;
00344                         }
00345                         
00346                         GL11.glDisable(GL11.GL_TEXTURE_2D);
00347                         GL11.glColor4f(.3f,.5f,1,.5f);
00348                         GL11.glPushMatrix();
00349                         GL11.glScalef(1,1,.1f);
00350                         GLSphereRenderer.renderSphere(2);
00351                         GL11.glPopMatrix();
00352                         GL11.glTranslatef(0,0,5);
00353                         GL11.glColor3f(.3f,.5f,1);
00354                         GLBoxRenderer.renderBox(.2f,.2f,10f);
00355                         GL11.glTranslatef(0,0,-5);
00356                         
00357                         if (distance!=0){ //show some echo
00358                                 GL11.glColor3f(1,1,1);
00359                                 GL11.glTranslatef(0,0,distance);
00360                                 GLSphereRenderer.renderSphere(1);                                                               
00361                         }                       
00362                 }
00363 
00365                 public float getCost(VisTrack track) {
00366                         if (distance==0) return Float.MAX_VALUE; 
00367                         
00368                         Vector3f pos=parent.traverse(this,track.current.pos); //get items current position   
00369                         
00370                         Vector3f tmp=new Vector3f();                                            //calculate items next position 
00371                         Vector3f.add(track.current.pos, track.current.dpos, tmp);
00372                         Vector3f pos2=parent.traverse(this, tmp);
00373                         
00374                         float dl=pos2.length()-pos.length();   // calculate velocity of distance change 
00375 //                      System.out.println(dl+" "+speed);
00376                         
00377                         float cost= Math.abs(pos.length()-distance)*WEIGHT_DIST 
00378                                   + Math.abs(dl-speed)             *WEIGHT_SPEED;
00379                         
00380                         return cost;
00381                 }
00382 
00388                 public void update(VisTrack track) {
00389                         
00390                         Vector3f pos=traverse(parent, new Vector3f(0,0,distance));
00391                         
00392                         //System.out.println(track.current.pos+" "+pos);
00393                         
00394                         if (track.current.pos==null) track.current.pos=pos;
00395                         else                         track.current.pos.set(pos); //lerp(track.current.pos, pos, .5f);
00396                         
00397                         Vector3f pos2=traverse(parent, new Vector3f(0,0,distance+speed));
00398                         Vector3f.sub(pos2, pos, track.current.dpos);
00399                         
00400                         track.variance=1f;
00401                         track.lastseen=System.currentTimeMillis();
00402                 }               
00403         }
00404         
00405         
00406         public VisNode addSonar(Vector3f pos, float heading, float elevation){
00407                 VisNode sonar= new VisSonar(pos,heading,elevation);
00408                 add(sonar);
00409                 return sonar;
00410         }
00411         
00412         public VisNode addCamera(Vector3f pos, float heading, float elevation, String ip){
00413                 VisNode cam= new VisCamera(pos,heading,elevation,ip);
00414                 add(cam);
00415                 return cam;
00416         }
00417         
00418         
00420         class VisSonarDummy extends VisSonar{
00421 
00422                 public VisSonarDummy(Vector3f pos, float heading, float pitch) {
00423                         super(pos, heading, pitch);
00424                 }
00425                 
00426                 float olddist=10; //hold last simulated items position
00427                 
00428                 int dir=1;
00429                 
00431                 void renderSelf() {
00432                         
00433                         if (Math.random()>.99f){ //ocassionally invoke a simulated receive! 
00434                                 
00435                                 /*if (distance>50 || distance < 0) dir=-dir;
00436                                 
00437                                 float d= dir * (float)Math.random();                            
00438                                 receive(olddist+d, dir*0.00002f/getRoot().client.dt);                           
00439                                 olddist=distance;
00440 */
00441                                 
00442                                 if (olddist>100 || olddist <= 5) dir=-dir;
00443                                 
00444                                 float d= dir * ((float)Math.random()*.2f+1);                            
00445                                 receive(olddist + 100 * d * getRoot().client.dt, d);                            
00446                                 olddist=distance;
00447 
00448                                 trackOne(this); //usually invoked by top class!!
00449                         }
00450                         super.renderSelf();
00451                 }               
00452         }
00453         
00454         final float SCALE=.1f, DSCALE=.01f; //scale for distance and speed
00455         // m,  m/s
00456 
00457         
00459         public void parseMsg(String[] msg){
00460                 if (!msg[1].matches("sonar[0-9]+")) return;
00461                 int id=Integer.parseInt(msg[1].replace("sonar", ""));
00462                 if (id>0 && id<=children.size()){
00463                         int distance=Integer.decode(msg[2]),speed=Integer.decode(msg[3]);
00464                         
00465                         if (speed>0x7FFF) speed-=0xFFFF;
00466                         if (Math.abs(speed)>30) speed=0; 
00467                         
00468                         ((VisSonar)children.get(id-1)).receive(distance*SCALE, speed*DSCALE);
00469                         
00470                         //System.out.println("Echo @ "+id+": "+distance+", "+speed);
00471                 }
00472         }
00473         
00476         void renderSelf() {             
00477 
00478         }
00479 
00480         
00481         
00482         HashMap<String, VisCamera> cameras=new HashMap<String, VisCamera>();
00488         public void addPortrait(String path, String ip) {
00489                 
00490                 if(Prefs.current.verbose) System.out.println("Cam "+ip+": "+path);
00491                 
00492                 Vector3f camera=cameras.get(ip).position;
00493                 if (camera==null) return;
00494                 if(Prefs.current.verbose) System.out.println("known. ");
00495                 
00496                 float minDist=Float.MAX_VALUE;
00497                 VisNode minTrack=null;
00498                 for (VisNode n: children)
00499                         if(n instanceof VisTrack){
00500                                 float dist=Vector3f.sub(n.position, camera,null).lengthSquared();
00501                                 if (dist<minDist){
00502                                         minDist=dist;
00503                                         minTrack=n;
00504                                 }
00505                         }
00506                 if (minTrack!=null)  minTrack.add(new VisImage(new Node(path), new Vector3f()));
00507         }
00508 
00509 }
00510 
00511 
00512 

Generated on Tue Apr 7 17:57:22 2009 for visclient by  doxygen 1.5.1