Skip to content

Commit d39f7fa

Browse files
Levi ArmstrongLevi-Armstrong
authored andcommitted
Add support for external tcp attached to kinematic link
1 parent c36118e commit d39f7fa

File tree

3 files changed

+79
-9
lines changed

3 files changed

+79
-9
lines changed

tesseract/tesseract_common/include/tesseract_common/manipulator_info.h

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,22 @@ class ToolCenterPoint
4949
* @brief Tool Center Point Defined by name
5050
* @param name The tool center point name
5151
* @param external The external TCP is used when the robot is holding the part verus the tool.
52+
* @note External should also be set to true your kinematic object which includes say a robot and
53+
* positioner, and the positioner has the tool and the robot is holding the part. Basically
54+
* anytime the tool is not attached to the tip link of the kinematic chain.
5255
*/
5356
ToolCenterPoint(const std::string& name, bool external = false);
5457

5558
/**
5659
* @brief Tool Center Point Defined by transform
5760
* @param transform The tool center point transform
5861
* @param external The external TCP is used when the robot is holding the part verus the tool.
62+
* @param external_frame If empty assumed relative to world, otherwise the provided tcp is relative to this link.
63+
* @note External should also be set to true your kinematic object which includes say a robot and
64+
* positioner, and the positioner has the tool and the robot is holding the part. Basically
65+
* anytime the tool is not attached to the tip link of the kinematic chain.
5966
*/
60-
ToolCenterPoint(const Eigen::Isometry3d& transform, bool external = false);
67+
ToolCenterPoint(const Eigen::Isometry3d& transform, bool external = false, std::string external_frame = "");
6168

6269
/**
6370
* @brief The Tool Center Point is empty
@@ -80,15 +87,26 @@ class ToolCenterPoint
8087
/**
8188
* @brief Check if tool center point is and external tcp which mean it is not defined
8289
* @details The external TCP is used when the robot is holding the part verus the tool.
90+
* External should also be set to true your kinematic object which includes say a robot and
91+
* positioner, and the positioner has the tool and the robot is holding the part. Basically
92+
* anytime the tool is not attached to the tip link of the kinematic chain.
8393
* @return True if and external TCP, otherwise the false
8494
*/
8595
bool isExternal() const;
8696

8797
/**
8898
* @brief Set the external property
8999
* @param value True if external tool center point, otherwise false
100+
* @param external_frame If an external tcp was defined as an Isometry then an external can be provided. If empty
101+
* assumed relative to world.
90102
*/
91-
void setExternal(bool value);
103+
void setExternal(bool value, std::string external_frame);
104+
105+
/**
106+
* @brief If an external tcp was defined as an Isometry then an external frame can be provided.
107+
* If empty assumed relative to world.
108+
*/
109+
const std::string& getExternalFrame() const;
92110

93111
/**
94112
* @brief Get the tool center point name
@@ -109,6 +127,7 @@ class ToolCenterPoint
109127
ret_val &= (name_ == other.name_);
110128
ret_val &= (transform_.isApprox(transform_, 1e-5));
111129
ret_val &= (external_ == other.external_);
130+
ret_val &= (external_frame_ == other.external_frame_);
112131
return ret_val;
113132
}
114133

@@ -117,8 +136,19 @@ class ToolCenterPoint
117136
std::string name_;
118137
Eigen::Isometry3d transform_;
119138

120-
/** @brief The external TCP is used when the robot is holding the part verus the tool. */
139+
/**
140+
* @brief The external TCP is used when the robot is holding the part verus the tool.
141+
* @details External should also be set to true your kinematic object which includes say a robot and
142+
* positioner, and the positioner has the tool and the robot is holding the part. Basically
143+
* anytime the tool is not attached to the tip link of the kinematic chain.
144+
*/
121145
bool external_{ false };
146+
147+
/**
148+
* @brief If an external tcp was defined as an Isometry then an external can be provided. If empty assumed relative to
149+
* world.
150+
*/
151+
std::string external_frame_;
122152
};
123153

124154
/**

tesseract/tesseract_common/src/manipulator_info.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,22 @@ namespace tesseract_common
3838
{
3939
ToolCenterPoint::ToolCenterPoint(const std::string& name, bool external) : type_(1), name_(name), external_(external) {}
4040

41-
ToolCenterPoint::ToolCenterPoint(const Eigen::Isometry3d& transform, bool external)
42-
: type_(2), transform_(transform), external_(external)
41+
ToolCenterPoint::ToolCenterPoint(const Eigen::Isometry3d& transform, bool external, std::string external_frame)
42+
: type_(2), transform_(transform), external_(external), external_frame_(std::move(external_frame))
4343
{
4444
}
4545

4646
bool ToolCenterPoint::empty() const { return (type_ == 0); }
4747
bool ToolCenterPoint::isString() const { return (type_ == 1); }
4848
bool ToolCenterPoint::isTransform() const { return (type_ == 2); }
4949
bool ToolCenterPoint::isExternal() const { return external_; }
50-
void ToolCenterPoint::setExternal(bool value) { external_ = value; }
50+
51+
const std::string& ToolCenterPoint::getExternalFrame() const { return external_frame_; }
52+
void ToolCenterPoint::setExternal(bool value, std::string external_frame)
53+
{
54+
external_ = value;
55+
external_frame_ = std::move(external_frame);
56+
}
5157

5258
const std::string& ToolCenterPoint::getString() const
5359
{
@@ -193,7 +199,15 @@ ManipulatorInfo::ManipulatorInfo(const tinyxml2::XMLElement& xml_element)
193199
if (status != tinyxml2::XML_SUCCESS)
194200
throw std::runtime_error("ManipulatorInfo: Error parsing TCP attribute external.");
195201

196-
tcp.setExternal(external);
202+
std::string external_frame;
203+
if (tcp_element->Attribute("external_frame") != nullptr)
204+
{
205+
tinyxml2::XMLError status = QueryStringAttribute(tcp_element, "external_frame", external_frame);
206+
if (status != tinyxml2::XML_SUCCESS)
207+
throw std::runtime_error("ManipulatorInfo: Error parsing TCP attribute external_frame.");
208+
}
209+
210+
tcp.setExternal(external, external_frame);
197211
}
198212
}
199213
}
@@ -272,6 +286,9 @@ tinyxml2::XMLElement* ManipulatorInfo::toXML(tinyxml2::XMLDocument& doc) const
272286

273287
xml_tcp->SetAttribute("wxyz", wxyz_string.str().c_str());
274288
xml_tcp->SetAttribute("external", tcp.isExternal());
289+
if (tcp.isExternal() && !tcp.getExternalFrame().empty())
290+
xml_tcp->SetAttribute("external_frame", tcp.getExternalFrame().c_str());
291+
275292
xml_manip_info->InsertEndChild(xml_tcp);
276293
}
277294

tesseract/tesseract_planning/tesseract_motion_planners/src/trajopt/profile/trajopt_default_plan_profile.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,37 @@ void TrajOptDefaultPlanProfile::apply(trajopt::ProblemConstructionInfo& pci,
119119
auto it = std::find(active_links.begin(), active_links.end(), mi.working_frame);
120120
if (it != active_links.end())
121121
{
122-
if (mi.tcp.isExternal())
122+
if (mi.tcp.isExternal() && mi.tcp.isString())
123+
{
124+
// If external, the part is attached to the robot so working frame is passed as link instead of target frame
125+
// Since it is a link name then it has the possibility to also be dynamic so need to check
126+
auto tcp_it = std::find(active_links.begin(), active_links.end(), mi.tcp.getString());
127+
if (tcp_it != active_links.end())
128+
{
129+
// target_tcp, index, target, tcp relative to robot tip link, coeffs, robot tip link, term_type
130+
ti = createDynamicCartesianWaypointTermInfo(Eigen::Isometry3d::Identity(),
131+
index,
132+
mi.tcp.getString(),
133+
cartesian_waypoint,
134+
cartesian_coeff,
135+
mi.working_frame,
136+
term_type);
137+
}
138+
else
139+
{
140+
ti = createCartesianWaypointTermInfo(
141+
tcp, index, "", cartesian_waypoint, cartesian_coeff, mi.working_frame, term_type);
142+
}
143+
}
144+
else if (mi.tcp.isExternal())
123145
{
124146
// If external, the part is attached to the robot so working frame is passed as link instead of target frame
125147
ti = createCartesianWaypointTermInfo(
126-
tcp, index, "", cartesian_waypoint, cartesian_coeff, mi.working_frame, term_type);
148+
tcp, index, mi.tcp.getExternalFrame(), cartesian_waypoint, cartesian_coeff, mi.working_frame, term_type);
127149
}
128150
else
129151
{
152+
// target_tcp, index, target, tcp relative to robot tip link, coeffs, robot tip link, term_type
130153
ti = createDynamicCartesianWaypointTermInfo(
131154
cartesian_waypoint, index, mi.working_frame, tcp, cartesian_coeff, pci.kin->getTipLinkName(), term_type);
132155
}

0 commit comments

Comments
 (0)