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 com.google.common.base.Preconditions;
00020
00021 import org.jboss.netty.buffer.ChannelBuffer;
00022 import org.ros.android.view.visualization.Color;
00023 import org.ros.android.view.visualization.Vertices;
00024 import org.ros.android.view.visualization.VisualizationView;
00025 import org.ros.message.MessageListener;
00026 import org.ros.namespace.GraphName;
00027 import org.ros.node.ConnectedNode;
00028 import org.ros.node.topic.Subscriber;
00029
00030 import java.nio.ByteOrder;
00031 import java.nio.FloatBuffer;
00032
00033 import javax.microedition.khronos.opengles.GL10;
00034
00035 import sensor_msgs.PointCloud2;
00036 import sensor_msgs.PointField;
00037
00044 public class PointCloud2DLayer extends SubscriberLayer<PointCloud2> implements TfLayer {
00045
00046 private static final Color FREE_SPACE_COLOR = Color.fromHexAndAlpha("377dfa", 0.1f);
00047 private static final Color OCCUPIED_SPACE_COLOR = Color.fromHexAndAlpha("377dfa", 0.3f);
00048 private static final float POINT_SIZE = 10.f;
00049
00050 private final Object mutex;
00051
00052 private GraphName frame;
00053 private FloatBuffer vertexFrontBuffer;
00054 private FloatBuffer vertexBackBuffer;
00055
00056 public PointCloud2DLayer(String topicName) {
00057 this(GraphName.of(topicName));
00058 }
00059
00060 public PointCloud2DLayer(GraphName topicName) {
00061 super(topicName, PointCloud2._TYPE);
00062 mutex = new Object();
00063 }
00064
00065 @Override
00066 public void draw(VisualizationView view, GL10 gl) {
00067 if (vertexFrontBuffer != null) {
00068 synchronized (mutex) {
00069 Vertices.drawTriangleFan(gl, vertexFrontBuffer, FREE_SPACE_COLOR);
00070
00071
00072 FloatBuffer pointVertices = vertexFrontBuffer.duplicate();
00073 pointVertices.position(3);
00074 Vertices.drawPoints(gl, pointVertices, OCCUPIED_SPACE_COLOR, POINT_SIZE);
00075 }
00076 }
00077 }
00078
00079 @Override
00080 public void onStart(VisualizationView view, ConnectedNode connectedNode) {
00081 super.onStart(view, connectedNode);
00082 Subscriber<PointCloud2> subscriber = getSubscriber();
00083 subscriber.addMessageListener(new MessageListener<PointCloud2>() {
00084 @Override
00085 public void onNewMessage(PointCloud2 pointCloud) {
00086 frame = GraphName.of(pointCloud.getHeader().getFrameId());
00087 updateVertexBuffer(pointCloud);
00088 }
00089 });
00090 }
00091
00092 private void updateVertexBuffer(final PointCloud2 pointCloud) {
00093
00094
00095
00096 Preconditions.checkArgument(pointCloud.getHeight() == 1);
00097 Preconditions.checkArgument(pointCloud.getIsDense());
00098 Preconditions.checkArgument(pointCloud.getFields().size() == 3);
00099 Preconditions.checkArgument(pointCloud.getFields().get(0).getDatatype() == PointField.FLOAT32);
00100 Preconditions.checkArgument(pointCloud.getFields().get(1).getDatatype() == PointField.FLOAT32);
00101 Preconditions.checkArgument(pointCloud.getFields().get(2).getDatatype() == PointField.FLOAT32);
00102 Preconditions.checkArgument(pointCloud.getPointStep() == 16);
00103 Preconditions.checkArgument(pointCloud.getData().order().equals(ByteOrder.LITTLE_ENDIAN));
00104 final int size = (pointCloud.getRowStep() / pointCloud.getPointStep() +
00105 1 ) * 3 ;
00106 if (vertexBackBuffer == null || vertexBackBuffer.capacity() < size) {
00107 vertexBackBuffer = Vertices.allocateBuffer(size);
00108 }
00109 vertexBackBuffer.clear();
00110
00111 vertexBackBuffer.put(0.f);
00112 vertexBackBuffer.put(0.f);
00113 vertexBackBuffer.put(0.f);
00114
00115 final ChannelBuffer buffer = pointCloud.getData();
00116 while (buffer.readable()) {
00117 vertexBackBuffer.put(buffer.readFloat());
00118 vertexBackBuffer.put(buffer.readFloat());
00119 vertexBackBuffer.put(0.f);
00120
00121 buffer.readFloat();
00122
00123 buffer.readFloat();
00124 }
00125 vertexBackBuffer.position(0);
00126 synchronized (mutex) {
00127 FloatBuffer tmp = vertexFrontBuffer;
00128 vertexFrontBuffer = vertexBackBuffer;
00129 vertexBackBuffer = tmp;
00130 }
00131 }
00132
00133 @Override
00134 public GraphName getFrame() {
00135 return frame;
00136 }
00137 }