Skip to content

Commit ba7d4b3

Browse files
committed
Added forward kinematics, replacing PlanarArmFK.
1 parent 2ce920b commit ba7d4b3

3 files changed

Lines changed: 96 additions & 92 deletions

File tree

src/kinematics/ArmFK2026.h

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#pragma once
2+
3+
#include "../navtypes.h"
4+
#include "ForwardArmKinematics.h"
5+
6+
#include <Eigen/Core>
7+
#include <cmath>
8+
9+
namespace kinematics {
10+
11+
/**
12+
* @brief Kinematics object for the 2026 arm in 3D space.
13+
*/
14+
class ArmFK2026 : public ForwardArmKinematics<3, 3> {
15+
public:
16+
/**
17+
* @brief Construct a new kinematics object.
18+
*
19+
* @param segLens The length of each arm segment (only shoulder and elbow).
20+
* @param jointMin The minimum angle of each joint.
21+
* @param jointMax The maximum angle of each joint.
22+
*/
23+
ArmFK2026(const navtypes::Vectord<3>& segLens,
24+
const navtypes::Vectord<3>& jointMin,
25+
const navtypes::Vectord<3>& jointMax)
26+
: segLens(segLens), jointMin(jointMin), jointMax(jointMax) {}
27+
28+
navtypes::Vectord<3> getSegLens() const override {
29+
return segLens;
30+
}
31+
32+
bool satisfiesConstraints(const navtypes::Vectord<3>& jointPos) const override {
33+
for (unsigned int i = 0; i < 3; i++) {
34+
if (jointPos[i] < jointMin[i] || jointPos[i] > jointMax[i]) {
35+
return false;
36+
}
37+
}
38+
return true;
39+
}
40+
41+
navtypes::Vectord<3> jointPosToEEPos(const navtypes::Vectord<3>& jointPos) const override {
42+
double theta_B = jointPos[0];
43+
double theta_S = jointPos[1];
44+
double theta_E = jointPos[2];
45+
46+
double l = segLens[1];
47+
double t = segLens[2];
48+
49+
double x = std::cos(theta_B) * (l * std::sin(theta_S) + t * std::cos(theta_E));
50+
double y = std::sin(theta_B) * (l * std::sin(theta_S) + t * std::cos(theta_E));
51+
double z = l * std::cos(theta_S) - t * std::sin(theta_E);
52+
53+
return Eigen::Vector3d(x, y, z);
54+
}
55+
56+
navtypes::Matrixd<3, 3> getJacobian(const navtypes::Vectord<3>& jointPos) const override {
57+
double theta_B = jointPos[0];
58+
double theta_S = jointPos[1];
59+
double theta_E = jointPos[2];
60+
61+
double l = segLens[1];
62+
double t = segLens[2];
63+
64+
Eigen::Matrix<double, 3, 3> J;
65+
66+
// Partial derivatives for X
67+
J(0, 0) = -std::sin(theta_B) * (l * std::sin(theta_S) + t * std::cos(theta_E));
68+
J(0, 1) = std::cos(theta_B) * (l * std::cos(theta_S));
69+
J(0, 2) = std::cos(theta_B) * (-t * std::sin(theta_E));
70+
71+
// Partial derivatives for Y
72+
J(1, 0) = std::cos(theta_B) * (l * std::sin(theta_S) + t * std::cos(theta_E));
73+
J(1, 1) = std::sin(theta_B) * (l * std::cos(theta_S));
74+
J(1, 2) = std::sin(theta_B) * (-t * std::sin(theta_E));
75+
76+
// Partial derivatives for Z
77+
J(2, 0) = 0.0; // The base rotation does not affect the Z height
78+
J(2, 1) = -l * std::sin(theta_S);
79+
J(2, 2) = -t * std::cos(theta_E);
80+
81+
return J;
82+
}
83+
84+
private:
85+
navtypes::Vectord<3> segLens;
86+
navtypes::Vectord<3> jointMin;
87+
navtypes::Vectord<3> jointMax;
88+
};
89+
90+
} // namespace kinematics
Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66
namespace kinematics {
77

8-
class 2026IKSolver : public InverseArmKinematics<3, 3> {
8+
class IKSolver2026 : public InverseArmKinematics<3, 3> {
99
public:
10-
2026IKSolver(std::shared_ptr<const ForwardArmKinematics<3, 3>> fk)
10+
IKSolver2026(std::shared_ptr<const ForwardArmKinematics<3, 3>> fk)
1111
: InverseArmKinematics<3, 3>(fk) {}
1212

1313
protected:
@@ -21,39 +21,32 @@ class 2026IKSolver : public InverseArmKinematics<3, 3> {
2121
double y = eePos[1];
2222
double z = eePos[2];
2323

24-
const double l = 0.5; // Shoulder-to-elbow length
25-
const double t = 0.4; // Elbow-to-wrist length
24+
navtypes::Vectord<3> segLens = this->fk->getSegLens();
25+
const double l = segLens[1];
26+
const double t = segLens[2];
2627

27-
// Pre-calculate reused terms
2828
double r_xy = std::sqrt(x*x + y*y);
2929
double r_xyz = std::sqrt(x*x + y*y + z*z);
3030

31-
// Calculate Base Angle
3231
double theta_B = std::atan2(y, x);
3332

34-
// Calculate Shoulder Angle (with physical limit check)
35-
// The value inside the arccos function:
3633
double acos_inner = (l*l + x*x + y*y + z*z - t*t) / (2 * l * r_xyz);
3734

38-
// Check if the target is physically reachable
3935
if (acos_inner < -1.0 || acos_inner > 1.0) {
4036
success = false;
41-
break;
37+
return targetAngles; // Return early on failure
4238
}
4339

4440
double theta_S = (M_PI / 2.0) - std::atan2(z, r_xy) - std::acos(acos_inner);
4541

46-
// Calculate Elbow Angle
4742
double elbow_y = -(z - l * std::cos(theta_S));
4843
double elbow_x = r_xy - l * std::sin(theta_S);
4944
double theta_E = std::atan2(elbow_y, elbow_x);
5045

51-
// Assign to the output vector
5246
targetAngles[0] = theta_B;
5347
targetAngles[1] = theta_S;
5448
targetAngles[2] = theta_E;
5549

56-
// If made it this far, the calculation was physically possible
5750
success = true;
5851
return targetAngles;
5952
}

src/kinematics/PlanarArmFK.h

Lines changed: 0 additions & 79 deletions
This file was deleted.

0 commit comments

Comments
 (0)