Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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;
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
00069
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
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
00109 for (int i = 0; i < ranges.length; i += stride) {
00110 float range = ranges[i];
00111
00112
00113
00114 if (minimumRange < range && range < maximumRange) {
00115
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 }