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.rosjava_geometry;
00018
00019 import com.google.common.annotations.VisibleForTesting;
00020
00021 import org.ros.message.Time;
00022
00029 public class Transform {
00030
00031 private Vector3 translation;
00032 private Quaternion rotationAndScale;
00033
00034 public static Transform fromTransformMessage(geometry_msgs.Transform message) {
00035 return new Transform(Vector3.fromVector3Message(message.getTranslation()),
00036 Quaternion.fromQuaternionMessage(message.getRotation()));
00037 }
00038
00039 public static Transform fromPoseMessage(geometry_msgs.Pose message) {
00040 return new Transform(Vector3.fromPointMessage(message.getPosition()),
00041 Quaternion.fromQuaternionMessage(message.getOrientation()));
00042 }
00043
00044 public static Transform identity() {
00045 return new Transform(Vector3.zero(), Quaternion.identity());
00046 }
00047
00048 public static Transform xRotation(double angle) {
00049 return new Transform(Vector3.zero(), Quaternion.fromAxisAngle(Vector3.xAxis(), angle));
00050 }
00051
00052 public static Transform yRotation(double angle) {
00053 return new Transform(Vector3.zero(), Quaternion.fromAxisAngle(Vector3.yAxis(), angle));
00054 }
00055
00056 public static Transform zRotation(double angle) {
00057 return new Transform(Vector3.zero(), Quaternion.fromAxisAngle(Vector3.zAxis(), angle));
00058 }
00059
00060 public static Transform translation(double x, double y, double z) {
00061 return new Transform(new Vector3(x, y, z), Quaternion.identity());
00062 }
00063
00064 public static Transform translation(Vector3 vector) {
00065 return new Transform(vector, Quaternion.identity());
00066 }
00067
00068 public Transform(Vector3 translation, Quaternion rotation) {
00069 this.translation = translation;
00070 this.rotationAndScale = rotation;
00071 }
00072
00080 public Transform multiply(Transform other) {
00081 return new Transform(apply(other.translation), apply(other.rotationAndScale));
00082 }
00083
00084 public Transform invert() {
00085 Quaternion inverseRotationAndScale = rotationAndScale.invert();
00086 return new Transform(inverseRotationAndScale.rotateAndScaleVector(translation.invert()),
00087 inverseRotationAndScale);
00088 }
00089
00090 public Vector3 apply(Vector3 vector) {
00091 return rotationAndScale.rotateAndScaleVector(vector).add(translation);
00092 }
00093
00094 public Quaternion apply(Quaternion quaternion) {
00095 return rotationAndScale.multiply(quaternion);
00096 }
00097
00098 public Transform scale(double factor) {
00099 return new Transform(translation, rotationAndScale.scale(Math.sqrt(factor)));
00100 }
00101
00102 public double getScale() {
00103 return rotationAndScale.getMagnitudeSquared();
00104 }
00105
00111 public double[] toMatrix() {
00112 double x = rotationAndScale.getX();
00113 double y = rotationAndScale.getY();
00114 double z = rotationAndScale.getZ();
00115 double w = rotationAndScale.getW();
00116 double mm = rotationAndScale.getMagnitudeSquared();
00117 return new double[] { mm - 2 * y * y - 2 * z * z, 2 * x * y + 2 * z * w, 2 * x * z - 2 * y * w,
00118 0, 2 * x * y - 2 * z * w, mm - 2 * x * x - 2 * z * z, 2 * y * z + 2 * x * w, 0,
00119 2 * x * z + 2 * y * w, 2 * y * z - 2 * x * w, mm - 2 * x * x - 2 * y * y, 0,
00120 translation.getX(), translation.getY(), translation.getZ(), 1 };
00121 }
00122
00123 public geometry_msgs.Transform toTransformMessage(geometry_msgs.Transform result) {
00124 result.setTranslation(translation.toVector3Message(result.getTranslation()));
00125 result.setRotation(rotationAndScale.toQuaternionMessage(result.getRotation()));
00126 return result;
00127 }
00128
00129 public geometry_msgs.Pose toPoseMessage(geometry_msgs.Pose result) {
00130 result.setPosition(translation.toPointMessage(result.getPosition()));
00131 result.setOrientation(rotationAndScale.toQuaternionMessage(result.getOrientation()));
00132 return result;
00133 }
00134
00135 public geometry_msgs.PoseStamped toPoseStampedMessage(FrameName frame, Time stamp,
00136 geometry_msgs.PoseStamped result) {
00137 result.getHeader().setFrameId(frame.toString());
00138 result.getHeader().setStamp(stamp);
00139 result.setPose(toPoseMessage(result.getPose()));
00140 return result;
00141 }
00142
00143 public boolean almostEquals(Transform other, double epsilon) {
00144 return translation.almostEquals(other.translation, epsilon)
00145 && rotationAndScale.almostEquals(other.rotationAndScale, epsilon);
00146 }
00147
00148 @VisibleForTesting
00149 Vector3 getTranslation() {
00150 return translation;
00151 }
00152
00153 @VisibleForTesting
00154 Quaternion getRotationAndScale() {
00155 return rotationAndScale;
00156 }
00157
00158 @Override
00159 public String toString() {
00160 return String.format("Transform<%s, %s>", translation, rotationAndScale);
00161 }
00162
00163 @Override
00164 public int hashCode() {
00165 final int prime = 31;
00166 int result = 1;
00167 result = prime * result + ((rotationAndScale == null) ? 0 : rotationAndScale.hashCode());
00168 result = prime * result + ((translation == null) ? 0 : translation.hashCode());
00169 return result;
00170 }
00171
00172 @Override
00173 public boolean equals(Object obj) {
00174 if (this == obj)
00175 return true;
00176 if (obj == null)
00177 return false;
00178 if (getClass() != obj.getClass())
00179 return false;
00180 Transform other = (Transform) obj;
00181 if (rotationAndScale == null) {
00182 if (other.rotationAndScale != null)
00183 return false;
00184 } else if (!rotationAndScale.equals(other.rotationAndScale))
00185 return false;
00186 if (translation == null) {
00187 if (other.translation != null)
00188 return false;
00189 } else if (!translation.equals(other.translation))
00190 return false;
00191 return true;
00192 }
00193 }