LaserScanLayer.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 org.ros.android.view.visualization.Camera;
00020 import org.ros.android.view.visualization.Color;
00021 import org.ros.android.view.visualization.Vertices;
00022 import org.ros.message.MessageListener;
00023 import org.ros.namespace.GraphName;
00024 import org.ros.node.ConnectedNode;
00025 import org.ros.node.topic.Subscriber;
00026 import org.ros.rosjava_geometry.FrameTransformTree;
00027 import org.ros.rosjava_geometry.FrameName;
00028 import sensor_msgs.LaserScan;
00029 
00030 import java.nio.FloatBuffer;
00031 
00032 import javax.microedition.khronos.opengles.GL10;
00033 
00040 public class LaserScanLayer extends SubscriberLayer<sensor_msgs.LaserScan> implements TfLayer {
00041 
00042   private static final Color FREE_SPACE_COLOR = Color.fromHexAndAlpha("00adff", 0.3f);
00043   private static final Color OCCUPIED_SPACE_COLOR = Color.fromHexAndAlpha("ffffff", 0.6f);
00044   private static final float LASER_SCAN_POINT_SIZE = 0.1f; // M
00045   private static final int LASER_SCAN_STRIDE = 15;
00046 
00047   private final Object mutex;
00048 
00049   private FrameName frame;
00050   private Camera camera;
00051   private FloatBuffer vertexFrontBuffer;
00052   private FloatBuffer vertexBackBuffer;
00053 
00054   public LaserScanLayer(String topicName) {
00055     this(GraphName.of(topicName));
00056   }
00057 
00058   public LaserScanLayer(GraphName topicName) {
00059     super(topicName, sensor_msgs.LaserScan._TYPE);
00060     mutex = new Object();
00061   }
00062 
00063   @Override
00064   public void draw(GL10 gl) {
00065     if (vertexFrontBuffer != null) {
00066       synchronized (mutex) {
00067         Vertices.drawTriangleFan(gl, vertexFrontBuffer, FREE_SPACE_COLOR);
00068         // Drop the first point which is required for the triangle fan but is
00069         // not a range reading.
00070         FloatBuffer pointVertices = vertexFrontBuffer.duplicate();
00071         pointVertices.position(3);
00072         Vertices.drawPoints(gl, pointVertices, OCCUPIED_SPACE_COLOR,
00073             (float) (LASER_SCAN_POINT_SIZE * camera.getZoom()));
00074       }
00075     }
00076   }
00077 
00078   @Override
00079   public void onStart(ConnectedNode connectedNode, android.os.Handler handler,
00080       FrameTransformTree frameTransformTree, Camera camera) {
00081     super.onStart(connectedNode, handler, frameTransformTree, camera);
00082     this.camera = camera;
00083     Subscriber<LaserScan> subscriber = getSubscriber();
00084     subscriber.addMessageListener(new MessageListener<LaserScan>() {
00085       @Override
00086       public void onNewMessage(LaserScan laserScan) {
00087         frame = FrameName.of(laserScan.getHeader().getFrameId());
00088         updateVertexBuffer(laserScan, LASER_SCAN_STRIDE);
00089       }
00090     });
00091   }
00092 
00093   private void updateVertexBuffer(LaserScan laserScan, int stride) {
00094     float[] ranges = laserScan.getRanges();
00095     int size = ((ranges.length / stride) + 2) * 3;
00096     if (vertexBackBuffer == null || vertexBackBuffer.capacity() < size) {
00097       vertexBackBuffer = Vertices.allocateBuffer(size);
00098     }
00099     vertexBackBuffer.clear();
00100     // We start with the origin of the triangle fan.
00101     vertexBackBuffer.put(0);
00102     vertexBackBuffer.put(0);
00103     vertexBackBuffer.put(0);
00104     float minimumRange = laserScan.getRangeMin();
00105     float maximumRange = laserScan.getRangeMax();
00106     float angle = laserScan.getAngleMin();
00107     float angleIncrement = laserScan.getAngleIncrement();
00108     // Calculate the coordinates of the laser range values.
00109     for (int i = 0; i < ranges.length; i += stride) {
00110       float range = ranges[i];
00111       // Ignore ranges that are outside the defined range. We are not overly
00112       // concerned about the accuracy of the visualization and this is makes it
00113       // look a lot nicer.
00114       if (minimumRange < range && range < maximumRange) {
00115         // x, y, z
00116         vertexBackBuffer.put((float) (range * Math.cos(angle)));
00117         vertexBackBuffer.put((float) (range * Math.sin(angle)));
00118         vertexBackBuffer.put(0);
00119       }
00120       angle += angleIncrement * stride;
00121     }
00122     vertexBackBuffer.position(0);
00123     synchronized (mutex) {
00124       FloatBuffer tmp = vertexFrontBuffer;
00125       LaserScanLayer.this.vertexFrontBuffer = vertexBackBuffer;
00126       vertexBackBuffer = tmp;
00127     }
00128   }
00129 
00130   @Override
00131   public FrameName getFrame() {
00132     return frame;
00133   }
00134 }


android_core
Author(s): Damon Kohler
autogenerated on Thu Aug 27 2015 12:11:33