OccupancyGridLayer.java
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2011 Google Inc.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
00005  * use this file except in compliance with the License. You may obtain a copy of
00006  * the License at
00007  *
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
00013  * License for the specific language governing permissions and limitations under
00014  * the License.
00015  */
00016 
00017 package org.ros.android.view.visualization.layer;
00018 
00019 import com.google.common.base.Preconditions;
00020 import com.google.common.collect.Lists;
00021 
00022 import org.jboss.netty.buffer.ChannelBuffer;
00023 import org.ros.android.view.visualization.TextureBitmap;
00024 import org.ros.android.view.visualization.VisualizationView;
00025 import org.ros.internal.message.MessageBuffers;
00026 import org.ros.message.MessageListener;
00027 import org.ros.namespace.GraphName;
00028 import org.ros.node.ConnectedNode;
00029 import org.ros.rosjava_geometry.Quaternion;
00030 import org.ros.rosjava_geometry.Transform;
00031 import org.ros.rosjava_geometry.Vector3;
00032 
00033 import java.util.List;
00034 
00035 import javax.microedition.khronos.opengles.GL10;
00036 
00040 public class OccupancyGridLayer extends SubscriberLayer<nav_msgs.OccupancyGrid> implements TfLayer {
00041 
00045   private static final int COLOR_OCCUPIED = 0xff111111;
00046 
00050   private static final int COLOR_FREE = 0xffffffff;
00051 
00055   private static final int COLOR_UNKNOWN = 0xffdddddd;
00056 
00061   private class Tile {
00062 
00063     private final ChannelBuffer pixelBuffer = MessageBuffers.dynamicBuffer();
00064     private final TextureBitmap textureBitmap = new TextureBitmap();
00065 
00069     private final float resolution;
00070 
00074     private Transform origin;
00075 
00079     private int stride;
00080 
00084     private boolean ready;
00085 
00086     public Tile(float resolution) {
00087       this.resolution = resolution;
00088       ready = false;
00089     }
00090 
00091     public void draw(VisualizationView view, GL10 gl) {
00092       if (ready) {
00093         textureBitmap.draw(view, gl);
00094       }
00095     }
00096 
00097     public void clearHandle() {
00098       textureBitmap.clearHandle();
00099     }
00100 
00101     public void writeInt(int value) {
00102       pixelBuffer.writeInt(value);
00103     }
00104 
00105     public void update() {
00106       Preconditions.checkNotNull(origin);
00107       Preconditions.checkNotNull(stride);
00108       textureBitmap.updateFromPixelBuffer(pixelBuffer, stride, resolution, origin, COLOR_UNKNOWN);
00109       pixelBuffer.clear();
00110       ready = true;
00111     }
00112 
00113     public void setOrigin(Transform origin) {
00114       this.origin = origin;
00115     }
00116 
00117     public void setStride(int stride) {
00118       this.stride = stride;
00119     }
00120   }
00121 
00122   private final List<Tile> tiles;
00123 
00124   private boolean ready;
00125   private GraphName frame;
00126   private GL10 previousGl;
00127 
00128   public OccupancyGridLayer(String topic) {
00129     this(GraphName.of(topic));
00130   }
00131 
00132   public OccupancyGridLayer(GraphName topic) {
00133     super(topic, nav_msgs.OccupancyGrid._TYPE);
00134     tiles = Lists.newCopyOnWriteArrayList();
00135     ready = false;
00136   }
00137 
00138   @Override
00139   public void draw(VisualizationView view, GL10 gl) {
00140     if (previousGl != gl) {
00141       for (Tile tile : tiles) {
00142         tile.clearHandle();
00143       }
00144       previousGl = gl;
00145     }
00146     if (ready) {
00147       for (Tile tile : tiles) {
00148         tile.draw(view, gl);
00149       }
00150     }
00151   }
00152 
00153   @Override
00154   public GraphName getFrame() {
00155     return frame;
00156   }
00157 
00158   @Override
00159   public void onStart(VisualizationView view, ConnectedNode connectedNode) {
00160     super.onStart(view, connectedNode);
00161     previousGl = null;
00162     getSubscriber().addMessageListener(new MessageListener<nav_msgs.OccupancyGrid>() {
00163       @Override
00164       public void onNewMessage(nav_msgs.OccupancyGrid message) {
00165         update(message);
00166       }
00167     });
00168   }
00169 
00170   private void update(nav_msgs.OccupancyGrid message) {
00171     final float resolution = message.getInfo().getResolution();
00172     final int width = message.getInfo().getWidth();
00173     final int height = message.getInfo().getHeight();
00174     final int numTilesWide = (int) Math.ceil(width / (float) TextureBitmap.STRIDE);
00175     final int numTilesHigh = (int) Math.ceil(height / (float) TextureBitmap.STRIDE);
00176     final int numTiles = numTilesWide * numTilesHigh;
00177     final Transform origin = Transform.fromPoseMessage(message.getInfo().getOrigin());
00178 
00179     while (tiles.size() < numTiles) {
00180       tiles.add(new Tile(resolution));
00181     }
00182 
00183     for (int y = 0; y < numTilesHigh; ++y) {
00184       for (int x = 0; x < numTilesWide; ++x) {
00185         final int tileIndex = y * numTilesWide + x;
00186         tiles.get(tileIndex).setOrigin(origin.multiply(new Transform(new Vector3(x *
00187             resolution * TextureBitmap.STRIDE,
00188             y * resolution * TextureBitmap.HEIGHT, 0.), Quaternion.identity())));
00189         if (x < numTilesWide - 1) {
00190           tiles.get(tileIndex).setStride(TextureBitmap.STRIDE);
00191         } else {
00192           tiles.get(tileIndex).setStride(width % TextureBitmap.STRIDE);
00193         }
00194       }
00195     }
00196 
00197     int x = 0;
00198     int y = 0;
00199     final ChannelBuffer buffer = message.getData();
00200     while (buffer.readable()) {
00201       Preconditions.checkState(y < height);
00202       final int tileIndex = (y / TextureBitmap.STRIDE) * numTilesWide + x / TextureBitmap.STRIDE;
00203       final byte pixel = buffer.readByte();
00204       if (pixel == -1) {
00205         tiles.get(tileIndex).writeInt(COLOR_UNKNOWN);
00206       } else {
00207         if (pixel < 50) {
00208           tiles.get(tileIndex).writeInt(COLOR_FREE);
00209         } else {
00210           tiles.get(tileIndex).writeInt(COLOR_OCCUPIED);
00211         }
00212       }
00213 
00214       ++x;
00215       if (x == width) {
00216         x = 0;
00217         ++y;
00218       }
00219     }
00220 
00221     for (Tile tile : tiles) {
00222       tile.update();
00223     }
00224 
00225     frame = GraphName.of(message.getHeader().getFrameId());
00226     ready = true;
00227   }
00228 }


android_core
Author(s): Damon Kohler
autogenerated on Thu Jun 6 2019 21:20:07