se2ez
joint.cpp
Go to the documentation of this file.
1 /* Author: Zachary Kingston */
2 
3 #include <iostream>
4 
5 #include <se2ez/core/log.h>
6 #include <se2ez/core/math.h>
7 #include <se2ez/core/joint.h>
8 
9 using namespace se2ez;
10 
11 const std::string Joint::TYPE_STRINGS[] = {"fixed", "float", "flying", "translate",
12  "prismatic", "revolute", "continuous"};
13 
15 {
16  for (unsigned int i = 0; i <= TYPE_MAX; ++i)
17  if (joint == TYPE_STRINGS[i])
18  return static_cast<Type>(i);
19 
20  throw std::invalid_argument("Not a valid joint type");
21 }
22 
24 {
25  if (type <= TYPE_MAX && type >= 0)
26  return TYPE_STRINGS[type];
27 
28  throw std::invalid_argument("Not a valid joint type");
29 }
30 
31 Joint::Joint(const std::string &name, Type type, const Eigen::VectorXd &lower, const Eigen::VectorXd &upper)
32  : type(type)
33  , joints([&]() {
35 
36  // Create active joints for each joint type, suffix type of joint to name.
37  switch (type)
38  {
39  case FLOAT:
40  case FLYING:
41  joints.emplace_back(name + ":x", KDL::Joint::TransX);
42  joints.emplace_back(name + ":y", KDL::Joint::TransY);
43  joints.emplace_back(name + ":t", KDL::Joint::RotZ);
44  break;
45  case TRANSLATE:
46  joints.emplace_back(name + ":x", KDL::Joint::TransX);
47  joints.emplace_back(name + ":y", KDL::Joint::TransY);
48  break;
49  case PRISMATIC:
50  joints.emplace_back(name + ":p", KDL::Joint::TransX);
51  break;
52  case REVOLUTE:
53  case CONTINUOUS:
54  joints.emplace_back(name + ":r", KDL::Joint::RotZ);
55  break;
56  case FIXED:
57  default:
58  break;
59  };
60 
61  // Add reference fixed joint so this joint's indices can be found easily.
62  joints.emplace_back(name, KDL::Joint::None);
63  return joints;
64  }())
66  , fixed(type == FIXED)
67  , n(joints.size() - 1)
68  , lower(lower)
69  , upper(upper)
70  , top_((continuous) ? 1 : 0)
71 {
72  if (upper.size() != lower.size())
73  throw std::invalid_argument("Upper and lower limits must be of same dimension.");
74 
75  if (continuous && upper.size() != (n - 1))
76  throw std::invalid_argument("Continuous joint limits must be of same dimension of joint!");
77 
78  else if (not continuous && upper.size() != n)
79  throw std::invalid_argument("Joint limits must be of same dimension of joint!");
80 }
81 
82 void Joint::enforceBounds(Eigen::Ref<Eigen::VectorXd> q) const
83 {
84  for (unsigned int i = 0; i < n - top_; ++i)
85  q[i] = (q[i] > upper[i]) ? upper[i] : ((q[i] < lower[i]) ? lower[i] : q[i]);
86 
87  if (continuous)
88  {
89  double v = fmod(q[n - 1], math::pipi);
90  v += (v < -math::pi) ? math::pipi : ((v >= math::pi) ? -math::pipi : 0);
91 
92  q[n - 1] = v;
93  }
94 }
95 
96 void Joint::setRandom(Eigen::Ref<Eigen::VectorXd> q) const
97 {
98  const auto &bounds = getBounds();
99  for (unsigned int i = 0; i < n; i++)
100  q[i] = math::uniformReal(bounds.first[i], bounds.second[i]);
101 }
102 
103 bool Joint::inBounds(const Eigen::Ref<const Eigen::VectorXd> &q) const
104 {
105  bool ret = true;
106  for (unsigned int i = 0; i < n - top_ && ret; ++i)
107  ret &= (q[i] <= upper[i]) && (q[i] >= lower[i]);
108 
109  if (continuous)
110  ret &= q[n - 1] < math::pi && q[n - 1] >= -math::pi;
111 
112  return ret;
113 }
114 
115 double Joint::distance(const Eigen::Ref<const Eigen::VectorXd> &a,
116  const Eigen::Ref<const Eigen::VectorXd> &b) const
117 {
118  double d = (a.head(n - top_) - b.head(n - top_)).norm();
119  if (continuous)
120  d += 0.5 * math::angleDistance(a[n - 1], b[n - 1]);
121 
122  return d;
123 }
124 
125 void Joint::interpolate(const Eigen::Ref<const Eigen::VectorXd> &from,
126  const Eigen::Ref<const Eigen::VectorXd> &to, double t,
127  Eigen::Ref<Eigen::VectorXd> state) const
128 {
129  for (unsigned int i = 0; i < n - top_; ++i)
130  state[i] = from[i] + (to[i] - from[i]) * t;
131 
132  if (continuous)
133  {
134  const unsigned int i = n - 1;
135  double diff = to[i] - from[i];
136  if (fabs(diff) <= math::pi)
137  state[i] = from[i] + diff * t;
138  else
139  {
140  double &v = state[i];
141  diff = ((diff > 0.0) ? math::pipi : -math::pipi) - diff;
142 
143  v = from[i] - diff * t;
144  v += (v > math::pi) ? -math::pipi : ((v < -math::pi) ? math::pipi : 0);
145  }
146  }
147 }
148 
150 {
151  if (continuous)
152  {
153  Eigen::VectorXd nlower(n);
154  Eigen::VectorXd nupper(n);
155 
156  nlower.head(n - 1) = lower;
157  nupper.head(n - 1) = upper;
158 
159  nlower[n - 1] = -math::pi;
160  nupper[n - 1] = math::pi;
161 
162  return std::make_pair(nlower, nupper);
163  }
164 
165  return std::make_pair(lower, upper);
166 }
167 
169 {
171  const auto &bounds = getBounds();
172  ss << log::format("J(%1%", typeToString(type));
173 
174  if (type != FIXED)
175  ss << log::format(" %1% - %2%)", tf::printVector(bounds.first), tf::printVector(bounds.second));
176  else
177  ss << ")";
178 
179  return ss.str();
180 }
std::pair< Eigen::VectorXd, Eigen::VectorXd > getBounds() const
Get the bounds for this joint. For continuous joints, [-pi, pi] is returned.
Definition: joint.cpp:149
static const std::string TYPE_STRINGS[]
String representation of joint type.
Definition: joint.h:51
bool inBounds(const Eigen::Ref< const Eigen::VectorXd > &q) const
Checks if joint limits are satisfied for a joint configuration.
Definition: joint.cpp:103
Revolute joint, rotates. Uses Euclidean metric.
Definition: joint.h:45
void setRandom(Eigen::Ref< Eigen::VectorXd > q) const
sets the Joint at a random state respecting the limits.
Definition: joint.cpp:96
Joint(const std::string &name, Type type, const Eigen::VectorXd &lower, const Eigen::VectorXd &upper)
Constructor. Takes in name of joint (the frame this joint is associated with, normally) and the joint...
Definition: joint.cpp:31
static const double pi
Definition: math.h:32
static const std::string & typeToString(const Type &type)
Converts a joint type into its string representation.
Definition: joint.cpp:23
double uniformReal(double lower, double upper)
Return a uniform random number between lower and upper.
Definition: math.cpp:217
Prismatic joint, extends along X-axis.
Definition: joint.h:44
Type
Type of joint.
Definition: joint.h:38
Revolute joint, rotates. Continuous rotation, uses SO(2) metric.
Definition: joint.h:46
void enforceBounds(Eigen::Ref< Eigen::VectorXd > q) const
Enforces joint limits on a joint configuration.
Definition: joint.cpp:82
const unsigned int top_
Top index for internal computations.
Definition: joint.h:148
const Eigen::VectorXd upper
Upper limits of this frame&#39;s joint value (closed).
Definition: joint.h:145
Fixed joint, just a rigid transformation.
Definition: joint.h:40
const Eigen::VectorXd lower
Lower limits of this frame&#39;s joint value (closed).
Definition: joint.h:144
Floating joint, free movement in SE(2). Continuous rotation, uses SE(2) metric.
Definition: joint.h:42
std::string printDebug() const
Print debug information about this frame.
Definition: joint.cpp:168
void interpolate(const Eigen::Ref< const Eigen::VectorXd > &from, const Eigen::Ref< const Eigen::VectorXd > &to, double t, Eigen::Ref< Eigen::VectorXd > state) const
Interpolate between two joint configurations.
Definition: joint.cpp:125
static const double pipi
Definition: math.h:33
static const unsigned int TYPE_MAX
Maximum value a joint type can have.
Definition: joint.h:49
T str(T... args)
T make_pair(T... args)
const std::vector< KDL::Joint > joints
Underlying KDL joints.
Definition: joint.h:139
static Type stringToType(const std::string &joint)
Try to convert a string into a joint type. Not case-sensitive.
Definition: joint.cpp:14
T size(T... args)
Translating joint, free X- and Y-axis movement.
Definition: joint.h:43
const bool fixed
Is this joint fixed?
Definition: joint.h:141
std::string printVector(const Eigen::VectorXd &v, unsigned int precision=4)
Returns a string of a vector&#39;s contents.
Definition: math.cpp:90
std::string format(const std::string &fmt, Args &&... args)
Definition: log.h:25
const bool continuous
Is this a continuous type joint?
Definition: joint.h:140
const Type type
Type of joint.
Definition: joint.h:138
Main namespace.
Definition: collision.h:11
const unsigned int n
Number of joints.
Definition: joint.h:142
double distance(const Eigen::Ref< const Eigen::VectorXd > &a, const Eigen::Ref< const Eigen::VectorXd > &b) const
Measures distance between two joint configurations.
Definition: joint.cpp:115
Floating joint, free movement in SE(2). Uses Euclidean metric.
Definition: joint.h:41
double angleDistance(double v1, double v2)
Return the minimum distance between two angles (wrapping from -pi to pi).
Definition: math.cpp:184
T emplace_back(T... args)