Skip to content
Snippets Groups Projects
Commit 378ee8c3 authored by Damon Kohler's avatar Damon Kohler
Browse files

Adds additional tests and methods to aid testing.

parent 9b50644f
No related branches found
No related tags found
No related merge requests found
...@@ -17,6 +17,9 @@ ...@@ -17,6 +17,9 @@
package org.ros.rosjava_geometry; package org.ros.rosjava_geometry;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import java.util.List;
/** /**
* A quaternion. * A quaternion.
...@@ -94,9 +97,9 @@ public class Quaternion { ...@@ -94,9 +97,9 @@ public class Quaternion {
* other.x, w * other.w - x * other.x - y * other.y - z * other.z); * other.x, w * other.w - x * other.x - y * other.y - z * other.z);
} }
public Vector3 rotateVector(Vector3 vector) { public Vector3 rotateAndScaleVector(Vector3 vector) {
Quaternion vectorQuaternion = new Quaternion(vector.getX(), vector.getY(), vector.getZ(), 0); Quaternion vectorQuaternion = new Quaternion(vector.getX(), vector.getY(), vector.getZ(), 0);
Quaternion rotatedQuaternion = multiply(vectorQuaternion.multiply(invert())); Quaternion rotatedQuaternion = multiply(vectorQuaternion.multiply(conjugate()));
return new Vector3(rotatedQuaternion.getX(), rotatedQuaternion.getY(), rotatedQuaternion.getZ()); return new Vector3(rotatedQuaternion.getX(), rotatedQuaternion.getY(), rotatedQuaternion.getZ());
} }
...@@ -136,6 +139,20 @@ public class Quaternion { ...@@ -136,6 +139,20 @@ public class Quaternion {
return result; return result;
} }
public boolean almostEquals(Quaternion other, double epsilon) {
List<Double> epsilons = Lists.newArrayList();
epsilons.add(x - other.x);
epsilons.add(y - other.y);
epsilons.add(z - other.z);
epsilons.add(w - other.w);
for (double e : epsilons) {
if (Math.abs(e) > epsilon) {
return false;
}
}
return true;
}
@Override @Override
public String toString() { public String toString() {
return String.format("Quaternion<x: %.4f, y: %.4f, z: %.4f, w: %.4f>", x, y, z, w); return String.format("Quaternion<x: %.4f, y: %.4f, z: %.4f, w: %.4f>", x, y, z, w);
......
...@@ -17,13 +17,10 @@ ...@@ -17,13 +17,10 @@
package org.ros.rosjava_geometry; package org.ros.rosjava_geometry;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
import org.ros.message.Time; import org.ros.message.Time;
import org.ros.namespace.GraphName; import org.ros.namespace.GraphName;
import java.util.List;
/** /**
* A transformation in terms of translation, rotation, and scale. * A transformation in terms of translation, rotation, and scale.
* *
...@@ -87,12 +84,12 @@ public class Transform { ...@@ -87,12 +84,12 @@ public class Transform {
public Transform invert() { public Transform invert() {
Quaternion inverseRotationAndScale = rotationAndScale.invert(); Quaternion inverseRotationAndScale = rotationAndScale.invert();
return new Transform(inverseRotationAndScale.rotateVector(translation.invert()), return new Transform(inverseRotationAndScale.rotateAndScaleVector(translation.invert()),
inverseRotationAndScale); inverseRotationAndScale);
} }
public Vector3 apply(Vector3 vector) { public Vector3 apply(Vector3 vector) {
return rotationAndScale.rotateVector(vector).add(translation); return rotationAndScale.rotateAndScaleVector(vector).add(translation);
} }
public Quaternion apply(Quaternion quaternion) { public Quaternion apply(Quaternion quaternion) {
...@@ -118,12 +115,10 @@ public class Transform { ...@@ -118,12 +115,10 @@ public class Transform {
double z = rotationAndScale.getZ(); double z = rotationAndScale.getZ();
double w = rotationAndScale.getW(); double w = rotationAndScale.getW();
double mm = rotationAndScale.getMagnitudeSquared(); double mm = rotationAndScale.getMagnitudeSquared();
return new double[] { return new double[] { mm - 2 * y * y - 2 * z * z, 2 * x * y + 2 * z * w, 2 * x * z - 2 * y * w,
mm - 2 * y * y - 2 * z * z, 2 * x * y + 2 * z * w, 2 * x * z - 2 * y * w, 0, 0, 2 * x * y - 2 * z * w, mm - 2 * x * x - 2 * z * z, 2 * y * z + 2 * x * w, 0,
2 * x * y - 2 * z * w, mm - 2 * x * x - 2 * z * z, 2 * y * z + 2 * x * w, 0,
2 * x * z + 2 * y * w, 2 * y * z - 2 * x * w, mm - 2 * x * x - 2 * y * y, 0, 2 * x * z + 2 * y * w, 2 * y * z - 2 * x * w, mm - 2 * x * x - 2 * y * y, 0,
translation.getX(), translation.getY(), translation.getZ(), 1 translation.getX(), translation.getY(), translation.getZ(), 1 };
};
} }
public geometry_msgs.Transform toTransformMessage(geometry_msgs.Transform result) { public geometry_msgs.Transform toTransformMessage(geometry_msgs.Transform result) {
...@@ -147,20 +142,8 @@ public class Transform { ...@@ -147,20 +142,8 @@ public class Transform {
} }
public boolean almostEquals(Transform other, double epsilon) { public boolean almostEquals(Transform other, double epsilon) {
List<Double> epsilons = Lists.newArrayList(); return translation.almostEquals(other.translation, epsilon)
epsilons.add(translation.getX() - other.getTranslation().getX()); && rotationAndScale.almostEquals(other.rotationAndScale, epsilon);
epsilons.add(translation.getY() - other.getTranslation().getY());
epsilons.add(translation.getZ() - other.getTranslation().getZ());
epsilons.add(rotationAndScale.getX() - other.getRotationAndScale().getX());
epsilons.add(rotationAndScale.getY() - other.getRotationAndScale().getY());
epsilons.add(rotationAndScale.getZ() - other.getRotationAndScale().getZ());
epsilons.add(rotationAndScale.getW() - other.getRotationAndScale().getW());
for (double e : epsilons) {
if (Math.abs(e) > epsilon) {
return false;
}
}
return true;
} }
@VisibleForTesting @VisibleForTesting
......
...@@ -16,6 +16,10 @@ ...@@ -16,6 +16,10 @@
package org.ros.rosjava_geometry; package org.ros.rosjava_geometry;
import com.google.common.collect.Lists;
import java.util.List;
/** /**
* A three dimensional vector. * A three dimensional vector.
* *
...@@ -78,6 +82,10 @@ public class Vector3 { ...@@ -78,6 +82,10 @@ public class Vector3 {
return new Vector3(x / getMagnitude(), y / getMagnitude(), z / getMagnitude()); return new Vector3(x / getMagnitude(), y / getMagnitude(), z / getMagnitude());
} }
public Vector3 scale(double factor) {
return new Vector3(x * factor, y * factor, z * factor);
}
public double getX() { public double getX() {
return x; return x;
} }
...@@ -90,8 +98,12 @@ public class Vector3 { ...@@ -90,8 +98,12 @@ public class Vector3 {
return z; return z;
} }
private double getMagnitudeSquared() {
return x * x + y * y + z * z;
}
public double getMagnitude() { public double getMagnitude() {
return Math.sqrt(x * x + y * y + z * z); return Math.sqrt(getMagnitudeSquared());
} }
public geometry_msgs.Vector3 toVector3Message(geometry_msgs.Vector3 result) { public geometry_msgs.Vector3 toVector3Message(geometry_msgs.Vector3 result) {
...@@ -108,6 +120,19 @@ public class Vector3 { ...@@ -108,6 +120,19 @@ public class Vector3 {
return result; return result;
} }
public boolean almostEquals(Vector3 other, double epsilon) {
List<Double> epsilons = Lists.newArrayList();
epsilons.add(x - other.x);
epsilons.add(y - other.y);
epsilons.add(z - other.z);
for (double e : epsilons) {
if (Math.abs(e) > epsilon) {
return false;
}
}
return true;
}
@Override @Override
public String toString() { public String toString() {
return String.format("Vector3<x: %.4f, y: %.4f, z: %.4f>", x, y, z); return String.format("Vector3<x: %.4f, y: %.4f, z: %.4f>", x, y, z);
......
...@@ -93,7 +93,7 @@ public class QuaternionTest { ...@@ -93,7 +93,7 @@ public class QuaternionTest {
public void testRotateVector() { public void testRotateVector() {
Quaternion quaternion = Quaternion.fromAxisAngle(Vector3.zAxis(), Math.PI / 2); Quaternion quaternion = Quaternion.fromAxisAngle(Vector3.zAxis(), Math.PI / 2);
Vector3 vector = new Vector3(1, 0, 0); Vector3 vector = new Vector3(1, 0, 0);
Vector3 rotated = quaternion.rotateVector(vector); Vector3 rotated = quaternion.rotateAndScaleVector(vector);
assertEquals(0, rotated.getX(), 1e-9); assertEquals(0, rotated.getX(), 1e-9);
assertEquals(1, rotated.getY(), 1e-9); assertEquals(1, rotated.getY(), 1e-9);
assertEquals(0, rotated.getZ(), 1e-9); assertEquals(0, rotated.getZ(), 1e-9);
......
...@@ -76,14 +76,45 @@ public class TransformTest { ...@@ -76,14 +76,45 @@ public class TransformTest {
Random random = new Random(); Random random = new Random();
random.setSeed(42); random.setSeed(42);
for (int i = 0; i < 10000; i++) { for (int i = 0; i < 10000; i++) {
Vector3 vector = new Vector3(random.nextDouble(), random.nextDouble(), random.nextDouble()); Vector3 vector = randomVector(random);
Quaternion quaternion = Quaternion quaternion = randomQuaternion(random);
new Quaternion(random.nextDouble(), random.nextDouble(), random.nextDouble(),
random.nextDouble());
Transform transform = new Transform(vector, quaternion); Transform transform = new Transform(vector, quaternion);
Transform inverse = transform.invert(); Transform inverse = transform.invert();
Transform neutral = transform.multiply(inverse); Transform neutral = transform.multiply(inverse);
assertTrue(neutral.almostEquals(Transform.identity(), 1e-9)); assertTrue(neutral.almostEquals(Transform.identity(), 1e-9));
} }
} }
@Test
public void testMultiplyRandom() {
Random random = new Random();
random.setSeed(42);
for (int i = 0; i < 10000; i++) {
Vector3 data = randomVector(random);
Vector3 vector1 = randomVector(random);
Vector3 vector2 = randomVector(random);
Quaternion quaternion1 = randomQuaternion(random);
Quaternion quaternion2 = randomQuaternion(random);
Transform transform1 = new Transform(vector1, quaternion1);
Transform transform2 = new Transform(vector2, quaternion2);
Vector3 result1 = transform1.apply(transform2.apply(data));
Vector3 result2 = transform1.multiply(transform2).apply(data);
assertTrue(result1.almostEquals(result2, 1e-9));
}
}
@Test
public void testScale() {
assertTrue(Vector3.xAxis().scale(2)
.almostEquals(Transform.identity().scale(2).apply(Vector3.xAxis()), 1e-9));
}
private Quaternion randomQuaternion(Random random) {
return new Quaternion(random.nextDouble(), random.nextDouble(), random.nextDouble(),
random.nextDouble());
}
private Vector3 randomVector(Random random) {
return new Vector3(random.nextDouble(), random.nextDouble(), random.nextDouble());
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment