diff --git a/Alignment/include/ActsAlignment/Kernel/Alignment.ipp b/Alignment/include/ActsAlignment/Kernel/Alignment.ipp index cf082d591e8..9e11bdbb09d 100644 --- a/Alignment/include/ActsAlignment/Kernel/Alignment.ipp +++ b/Alignment/include/ActsAlignment/Kernel/Alignment.ipp @@ -164,9 +164,6 @@ ActsAlignment::Alignment::updateAlignmentParameters( // 1. The original transform const Acts::Vector3& oldCenter = surface->center(gctx); const Acts::Transform3& oldTransform = surface->transform(gctx); - const Acts::RotationMatrix3& oldRotation = oldTransform.rotation(); - // The elements stored below is (rotZ, rotY, rotX) - const Acts::Vector3& oldEulerAngles = oldRotation.eulerAngles(2, 1, 0); // 2. The delta transform deltaAlignmentParam = alignResult.deltaAlignmentParameters.segment( @@ -180,18 +177,17 @@ ActsAlignment::Alignment::updateAlignmentParameters( // 3. The new transform const Acts::Vector3 newCenter = oldCenter + deltaCenter; - // The rotation around global z axis - Acts::AngleAxis3 rotZ(oldEulerAngles(0) + deltaEulerAngles(2), - Acts::Vector3::UnitZ()); - // The rotation around global y axis - Acts::AngleAxis3 rotY(oldEulerAngles(1) + deltaEulerAngles(1), - Acts::Vector3::UnitY()); - // The rotation around global x axis - Acts::AngleAxis3 rotX(oldEulerAngles(2) + deltaEulerAngles(0), - Acts::Vector3::UnitX()); - Eigen::Quaternion newRotation = rotZ * rotY * rotX; - const Acts::Transform3 newTransform = - Acts::Translation3(newCenter) * newRotation; + Acts::Transform3 newTransform = oldTransform; + newTransform.translation() = newCenter; + // Rotation first around fixed local x, then around fixed local y, and last + // around fixed local z, this is the same as first around local z, then + // around new loca y, and last around new local x below + newTransform *= + Acts::AngleAxis3(deltaEulerAngles(2), Acts::Vector3::UnitZ()); + newTransform *= + Acts::AngleAxis3(deltaEulerAngles(1), Acts::Vector3::UnitY()); + newTransform *= + Acts::AngleAxis3(deltaEulerAngles(0), Acts::Vector3::UnitX()); // 4. Update the aligned transform //@Todo: use a better way to handle this (need dynamic cast to inherited diff --git a/Core/include/Acts/Definitions/Alignment.hpp b/Core/include/Acts/Definitions/Alignment.hpp index d906f4fabbf..68e9cfa358d 100644 --- a/Core/include/Acts/Definitions/Alignment.hpp +++ b/Core/include/Acts/Definitions/Alignment.hpp @@ -24,7 +24,7 @@ enum AlignmentIndices : unsigned int { eAlignmentCenter0 = 0u, eAlignmentCenter1 = eAlignmentCenter0 + 1u, eAlignmentCenter2 = eAlignmentCenter0 + 2u, - // Rotation angle around global x/y/z axis of geometry object + // Rotation angle around local x/y/z axis of geometry object eAlignmentRotation0 = 3u, eAlignmentRotation1 = eAlignmentRotation0 + 1u, eAlignmentRotation2 = eAlignmentRotation0 + 2u, diff --git a/Core/include/Acts/Surfaces/detail/AlignmentHelper.hpp b/Core/include/Acts/Surfaces/detail/AlignmentHelper.hpp index f69de328ae1..9dd5ddad59a 100644 --- a/Core/include/Acts/Surfaces/detail/AlignmentHelper.hpp +++ b/Core/include/Acts/Surfaces/detail/AlignmentHelper.hpp @@ -23,13 +23,16 @@ using RotationToAxes = std::tuple; /// @brief Evaluate the derivative of local frame axes vector w.r.t. -/// its rotation around global x/y/z axis +/// its rotation around local x/y/z axis /// @Todo: add parameter for rotation axis order /// -/// @param rotation The rotation that help place the surface +/// @param compositeRotation The rotation that help places the composite object being rotated +/// @param relRotation The relative rotation of the surface with respect to the composite object being rotated /// /// @return Derivative of local frame x/y/z axis vector w.r.t. its -/// rotation angles (extrinsic Euler angles) around global x/y/z axis -RotationToAxes rotationToLocalAxesDerivative(const RotationMatrix3& rotation); +/// rotation angles (extrinsic Euler angles) around local x/y/z axis +RotationToAxes rotationToLocalAxesDerivative( + const RotationMatrix3& compositeRotation, + const RotationMatrix3& relRotation = RotationMatrix3::Identity()); } // namespace Acts::detail diff --git a/Core/src/Surfaces/detail/AlignmentHelper.cpp b/Core/src/Surfaces/detail/AlignmentHelper.cpp index 0d78ea3f704..e208a541120 100644 --- a/Core/src/Surfaces/detail/AlignmentHelper.cpp +++ b/Core/src/Surfaces/detail/AlignmentHelper.cpp @@ -13,41 +13,79 @@ #include Acts::detail::RotationToAxes Acts::detail::rotationToLocalAxesDerivative( - const RotationMatrix3& rotation) { - // Get Euler angles for rotation represented by rotZ * rotY * rotX, i.e. - // first rotation around x axis, then y axis, last z axis - // The elements stored in rotAngles is (rotZ, rotY, rotX) - const Vector3 rotAngles = rotation.eulerAngles(2, 1, 0); - double sx = std::sin(rotAngles(2)); - double cx = std::cos(rotAngles(2)); - double sy = std::sin(rotAngles(1)); - double cy = std::cos(rotAngles(1)); - double sz = std::sin(rotAngles(0)); - double cz = std::cos(rotAngles(0)); - // rotZ * rotY * rotX = - // [ cz*cy cz*sy*sx-cx*sz sz*sx+cz*cx*sy ] - // [ cy*sz cz*cx+sz*sy*sx cx*sz*sy-cz*sx ] - // [ -sy cy*sx cy*cx ] + const RotationMatrix3& compositeRotation, + const RotationMatrix3& relRotation) { + // Suppose the local axes of the composite have small rotation first around + // its original local x axis by alpha, then around its original local y by + // beta, then last around its original local z by gamma, the new rotation + // matrix of the composite is then compositeRotation*deltaRotation, where + // deltaRotation has the following form: + // | cbeta*cgamma salpha*sbeta*cgamma-calpha*sgamma calpha*sbeta*cgamma + + // salpha*sgamma|, | cbeta*sgamma salpha*sbeta*sgamma+calpha*cgamma + // calpha*sbeta*sgamma-salpha*cgamma |, | -sbeta salpha*cbeta + // calpha*cbeta | where prefix 's' means sin and 'c' + // means cos, then: + // 1) the derivatives of new local x axis of the composite + // w.r.t. (alpha, beta, gamma) is rotToCompositeLocalXAxis = + // compositeRotation* |0 0 0|, + // |0 0 1| + // |0 -1 0| + // 2) the derivatives of new local y axis of the composite + // w.r.t. (alpha, beta, gamma) is rotToCompositeLocalYAxis = + // compositeRotation* |0 0 -1|, + // |0 0 0| + // |1 0 0| + // 3) the derivatives of new local z axis of the composite + // w.r.t. (alpha, beta, gamma) is rotToCompositeLocalZAxis = + // compositeRotation* | 0 1 0|, + // |-1 0 0| + // | 0 0 0| + + // The object rotation is objectRotation = compositeRotation*relRotation, then + // 1) the derivate of the new local + // x axis of the object w.r.t. (alpha, beta, gamma) is + // rotToCompositeLocalXAxis * relRotation(0,0) + + // rotToCompositeLocalYAxis*relRotation(1,0) + + // rotToCompositeLocalZAxis*relRotation(2,0), + // 2) the derivate of the new local + // y axis of the object w.r.t. (alpha, beta, gamma) is + // rotToCompositeLocalXAxis * relRotation(0,1) + + // rotToCompositeLocalYAxis*relRotation(1,1) + + // rotToCompositeLocalZAxis*relRotation(2,1), + // 3) the derivate of the new local + // z axis of the object w.r.t. (alpha, beta, gamma) is + // rotToCompositeLocalXAxis * relRotation(0,2) + + // rotToCompositeLocalYAxis*relRotation(1,2) + + // rotToCompositeLocalZAxis*relRotation(2,2), // Derivative of local x axis w.r.t. (rotX, rotY, rotZ) - RotationMatrix3 rotToLocalXAxis = RotationMatrix3::Zero(); - rotToLocalXAxis.col(0) = Vector3(0, 0, 0); - rotToLocalXAxis.col(1) = Vector3(-cz * sy, -sz * sy, -cy); - rotToLocalXAxis.col(2) = Vector3(-sz * cy, cz * cy, 0); + RotationMatrix3 rotToCompositeLocalXAxis = RotationMatrix3::Zero(); + rotToCompositeLocalXAxis.col(0) = compositeRotation * Vector3(0, 0, 0); + rotToCompositeLocalXAxis.col(1) = compositeRotation * Vector3(0, 0, -1); + rotToCompositeLocalXAxis.col(2) = compositeRotation * Vector3(0, 1, 0); // Derivative of local y axis w.r.t. (rotX, rotY, rotZ) - RotationMatrix3 rotToLocalYAxis = RotationMatrix3::Zero(); - rotToLocalYAxis.col(0) = - Vector3(cz * sy * cx + sz * sx, sz * sy * cx - cz * sx, cy * cx); - rotToLocalYAxis.col(1) = Vector3(cz * cy * sx, sz * cy * sx, -sy * sx); - rotToLocalYAxis.col(2) = - Vector3(-sz * sy * sx - cz * cx, cz * sy * sx - sz * cx, 0); + RotationMatrix3 rotToCompositeLocalYAxis = RotationMatrix3::Zero(); + rotToCompositeLocalYAxis.col(0) = compositeRotation * Vector3(0, 0, 1); + rotToCompositeLocalYAxis.col(1) = compositeRotation * Vector3(0, 0, 0); + rotToCompositeLocalYAxis.col(2) = compositeRotation * Vector3(-1, 0, 0); // Derivative of local z axis w.r.t. (rotX, rotY, rotZ) + RotationMatrix3 rotToCompositeLocalZAxis = RotationMatrix3::Zero(); + rotToCompositeLocalZAxis.col(0) = compositeRotation * Vector3(0, -1, 0); + rotToCompositeLocalZAxis.col(1) = compositeRotation * Vector3(1, 0, 0); + rotToCompositeLocalZAxis.col(2) = compositeRotation * Vector3(0, 0, 0); + + RotationMatrix3 rotToLocalXAxis = RotationMatrix3::Zero(); + RotationMatrix3 rotToLocalYAxis = RotationMatrix3::Zero(); RotationMatrix3 rotToLocalZAxis = RotationMatrix3::Zero(); - rotToLocalZAxis.col(0) = - Vector3(sz * cx - cz * sy * sx, -sz * sy * sx - cz * cx, -cy * sx); - rotToLocalZAxis.col(1) = Vector3(cz * cy * cx, sz * cy * cx, -sy * cx); - rotToLocalZAxis.col(2) = - Vector3(cz * sx - sz * sy * cx, cz * sy * cx + sz * sx, 0); + rotToLocalXAxis = rotToCompositeLocalXAxis * relRotation(0, 0) + + rotToCompositeLocalYAxis * relRotation(1, 0) + + rotToCompositeLocalZAxis * relRotation(2, 0); + rotToLocalYAxis = rotToCompositeLocalXAxis * relRotation(0, 1) + + rotToCompositeLocalYAxis * relRotation(1, 1) + + rotToCompositeLocalZAxis * relRotation(2, 1); + rotToLocalZAxis = rotToCompositeLocalXAxis * relRotation(0, 2) + + rotToCompositeLocalYAxis * relRotation(1, 2) + + rotToCompositeLocalZAxis * relRotation(2, 2); return std::make_tuple(std::move(rotToLocalXAxis), std::move(rotToLocalYAxis), std::move(rotToLocalZAxis)); diff --git a/Tests/UnitTests/Core/Surfaces/AlignmentHelperTests.cpp b/Tests/UnitTests/Core/Surfaces/AlignmentHelperTests.cpp index ada970908f3..3f1f2d8e5fb 100644 --- a/Tests/UnitTests/Core/Surfaces/AlignmentHelperTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/AlignmentHelperTests.cpp @@ -53,25 +53,21 @@ BOOST_AUTO_TEST_CASE(alignment_helper_test) { // Calculate the expected derivative of local x axis to its rotation RotationMatrix3 expRotToXAxis = RotationMatrix3::Zero(); - expRotToXAxis.col(0) = Vector3(0, 0, 0); - expRotToXAxis.col(1) = Vector3(-cz * sy, -sz * sy, -cy); - expRotToXAxis.col(2) = Vector3(-sz * cy, cz * cy, 0); + expRotToXAxis.col(0) = expRot * Vector3(0, 0, 0); + expRotToXAxis.col(1) = expRot * Vector3(0, 0, -1); + expRotToXAxis.col(2) = expRot * Vector3(0, 1, 0); // Calculate the expected derivative of local y axis to its rotation RotationMatrix3 expRotToYAxis = RotationMatrix3::Zero(); - expRotToYAxis.col(0) = - Vector3(cz * sy * cx + sz * sx, sz * sy * cx - cz * sx, cy * cx); - expRotToYAxis.col(1) = Vector3(cz * cy * sx, sz * cy * sx, -sy * sx); - expRotToYAxis.col(2) = - Vector3(-sz * sy * sx - cz * cx, cz * sy * sx - sz * cx, 0); + expRotToYAxis.col(0) = expRot * Vector3(0, 0, 1); + expRotToYAxis.col(1) = expRot * Vector3(0, 0, 0); + expRotToYAxis.col(2) = expRot * Vector3(-1, 0, 0); // Calculate the expected derivative of local z axis to its rotation RotationMatrix3 expRotToZAxis = RotationMatrix3::Zero(); - expRotToZAxis.col(0) = - Vector3(sz * cx - cz * sy * sx, -sz * sy * sx - cz * cx, -cy * sx); - expRotToZAxis.col(1) = Vector3(cz * cy * cx, sz * cy * cx, -sy * cx); - expRotToZAxis.col(2) = - Vector3(cz * sx - sz * sy * cx, cz * sy * cx + sz * sx, 0); + expRotToZAxis.col(0) = expRot * Vector3(0, -1, 0); + expRotToZAxis.col(1) = expRot * Vector3(1, 0, 0); + expRotToZAxis.col(2) = expRot * Vector3(0, 0, 0); // Construct a transform Translation3 translation(Vector3(0., 0., 0.)); diff --git a/Tests/UnitTests/Core/Surfaces/PlaneSurfaceTests.cpp b/Tests/UnitTests/Core/Surfaces/PlaneSurfaceTests.cpp index 99df4dab774..96f0371735d 100644 --- a/Tests/UnitTests/Core/Surfaces/PlaneSurfaceTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/PlaneSurfaceTests.cpp @@ -336,7 +336,7 @@ BOOST_AUTO_TEST_CASE(PlaneSurfaceAlignment) { direction); // The expected results AlignmentToPathMatrix expAlignToPath = AlignmentToPathMatrix::Zero(); - expAlignToPath << 1, 0, 0, 2, -1, -2; + expAlignToPath << 1, 0, 0, 2, -1, 0; // Check if the calculated derivative is as expected CHECK_CLOSE_ABS(alignToPath, expAlignToPath, 1e-10); @@ -362,9 +362,9 @@ BOOST_AUTO_TEST_CASE(PlaneSurfaceAlignment) { alignToBound.block<1, 6>(eBoundLoc1, eAlignmentCenter0); // The expected results AlignmentToPathMatrix expAlignToloc0; - expAlignToloc0 << 0, 0, 1, 0, 0, 0; + expAlignToloc0 << 0, 0, 1, 0, 0, 2; AlignmentToPathMatrix expAlignToloc1; - expAlignToloc1 << 0, -1, 0, 0, 0, 0; + expAlignToloc1 << 0, -1, 0, 0, 0, -1; // Check if the calculated derivatives are as expected CHECK_CLOSE_ABS(alignToloc0, expAlignToloc0, 1e-10); CHECK_CLOSE_ABS(alignToloc1, expAlignToloc1, 1e-10);