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 android.content.Context;
00022 import android.os.Handler;
00023 import android.view.GestureDetector;
00024 import android.view.MotionEvent;
00025 import org.ros.android.view.visualization.Camera;
00026 import org.ros.android.view.visualization.VisualizationView;
00027 import org.ros.android.view.visualization.shape.PoseShape;
00028 import org.ros.android.view.visualization.shape.Shape;
00029 import org.ros.namespace.GraphName;
00030 import org.ros.node.ConnectedNode;
00031 import org.ros.node.Node;
00032 import org.ros.node.topic.Publisher;
00033 import org.ros.rosjava_geometry.FrameTransformTree;
00034 import org.ros.rosjava_geometry.Transform;
00035 import org.ros.rosjava_geometry.Vector3;
00036
00037 import javax.microedition.khronos.opengles.GL10;
00038
00042 public class PosePublisherLayer extends DefaultLayer {
00043
00044 private final Context context;
00045
00046 private Shape shape;
00047 private Publisher<geometry_msgs.PoseStamped> posePublisher;
00048 private boolean visible;
00049 private GraphName topic;
00050 private GestureDetector gestureDetector;
00051 private Transform pose;
00052 private Camera camera;
00053 private ConnectedNode connectedNode;
00054
00055 public PosePublisherLayer(String topic, Context context) {
00056 this(GraphName.of(topic), context);
00057 }
00058
00059 public PosePublisherLayer(GraphName topic, Context context) {
00060 this.topic = topic;
00061 this.context = context;
00062 visible = false;
00063 }
00064
00065 @Override
00066 public void draw(GL10 gl) {
00067 if (visible) {
00068 Preconditions.checkNotNull(pose);
00069 shape.draw(gl);
00070 }
00071 }
00072
00073 private double angle(double x1, double y1, double x2, double y2) {
00074 double deltaX = x1 - x2;
00075 double deltaY = y1 - y2;
00076 return Math.atan2(deltaY, deltaX);
00077 }
00078
00079 @Override
00080 public boolean onTouchEvent(VisualizationView view, MotionEvent event) {
00081 if (visible) {
00082 Preconditions.checkNotNull(pose);
00083 if (event.getAction() == MotionEvent.ACTION_MOVE) {
00084 Vector3 poseVector = pose.apply(Vector3.zero());
00085 Vector3 pointerVector = camera.toMetricCoordinates((int) event.getX(), (int) event.getY());
00086 double angle =
00087 angle(pointerVector.getX(), pointerVector.getY(), poseVector.getX(), poseVector.getY());
00088 pose = Transform.translation(poseVector).multiply(Transform.zRotation(angle));
00089 shape.setTransform(pose);
00090 return true;
00091 }
00092 if (event.getAction() == MotionEvent.ACTION_UP) {
00093 posePublisher.publish(pose.toPoseStampedMessage(camera.getFrame(),
00094 connectedNode.getCurrentTime(), posePublisher.newMessage()));
00095 visible = false;
00096 return true;
00097 }
00098 }
00099 gestureDetector.onTouchEvent(event);
00100 return false;
00101 }
00102
00103 @Override
00104 public void onStart(ConnectedNode connectedNode, Handler handler,
00105 FrameTransformTree frameTransformTree, final Camera camera) {
00106 this.connectedNode = connectedNode;
00107 this.camera = camera;
00108 shape = new PoseShape(camera);
00109 posePublisher = connectedNode.newPublisher(topic, "geometry_msgs/PoseStamped");
00110 handler.post(new Runnable() {
00111 @Override
00112 public void run() {
00113 gestureDetector =
00114 new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
00115 @Override
00116 public void onLongPress(MotionEvent e) {
00117 pose =
00118 Transform.translation(camera.toMetricCoordinates((int) e.getX(), (int) e.getY()));
00119 shape.setTransform(pose);
00120 visible = true;
00121 }
00122 });
00123 }
00124 });
00125 }
00126
00127 @Override
00128 public void onShutdown(VisualizationView view, Node node) {
00129 posePublisher.shutdown();
00130 }
00131 }