Skip to content

Commit 7239e5e

Browse files
Levi ArmstrongLevi-Armstrong
authored andcommitted
Add ability to replace link and joint pair where the link is the child link of joint
1 parent ea5241d commit 7239e5e

File tree

4 files changed

+161
-9
lines changed

4 files changed

+161
-9
lines changed

tesseract_environment/include/tesseract_environment/core/commands/add_link_command.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,29 @@ class AddLinkCommand : public Command
7272
/**
7373
* @brief Adds a link and joint in the environment
7474
*
75-
* If the link or joint exists:
75+
* If the link and joint exist and replace is allowed
76+
*
77+
* This command will replace both link and joint if the link is the child link, otherwise this results in error
78+
*
79+
* If the link and joint exist and replace is not allowed
80+
*
81+
* This command should result in an error
82+
*
83+
* If the link or joint only exists:
7684
*
7785
* This command should result in an error
7886
*
7987
* @param link The link to be added to the graph
8088
* @param joint The joint to be used to attach link to environment
81-
* @param replace_allowed If true then if the link exists it will be replaced, otherwise if false it will fail.
89+
* @param replace_allowed If true then if the link and joint exists it will be replaced, otherwise if false it will
90+
* fail.
8291
*/
83-
AddLinkCommand(const tesseract_scene_graph::Link& link, const tesseract_scene_graph::Joint& joint)
92+
AddLinkCommand(const tesseract_scene_graph::Link& link,
93+
const tesseract_scene_graph::Joint& joint,
94+
bool replace_allowed = false)
8495
: link_(std::make_shared<tesseract_scene_graph::Link>(link.clone()))
8596
, joint_(std::make_shared<tesseract_scene_graph::Joint>(joint.clone()))
97+
, replace_allowed_(replace_allowed)
8698
{
8799
if (joint_->child_link_name != link.getName())
88100
throw std::runtime_error("AddLinkCommand: The provided joint child link name must equal the name of the provided "

tesseract_environment/src/core/environment.cpp

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,7 +1063,10 @@ bool Environment::addSceneGraph(const tesseract_scene_graph::SceneGraph& scene_g
10631063

10641064
bool Environment::applyAddCommand(AddLinkCommand::ConstPtr cmd)
10651065
{
1066+
// The command should not allow this to occur but adding an assert to catch if something changes
10661067
assert(!(!cmd->getLink() && !cmd->getJoint()));
1068+
assert(!((cmd->getLink() != nullptr) && (cmd->getJoint() != nullptr) &&
1069+
(cmd->getJoint()->child_link_name != cmd->getLink()->getName())));
10671070

10681071
bool link_exists = false;
10691072
bool joint_exists = false;
@@ -1088,16 +1091,28 @@ bool Environment::applyAddCommand(AddLinkCommand::ConstPtr cmd)
10881091
return false;
10891092
}
10901093

1091-
if ((link_exists && cmd->getJoint()))
1094+
if ((joint_exists && !cmd->replaceAllowed()))
10921095
{
1093-
CONSOLE_BRIDGE_logWarn("Tried to add link (%s) which already exists with a joint provided. This is not supported.",
1096+
CONSOLE_BRIDGE_logWarn("Tried to replace link (%s) and joint (%s) where the joint exist but the link does not. "
1097+
"This is not supported.",
1098+
link_name.c_str(),
1099+
joint_name.c_str());
1100+
return false;
1101+
}
1102+
1103+
if (!link_exists && joint_exists)
1104+
{
1105+
CONSOLE_BRIDGE_logWarn("Tried to add link (%s) which already exists with a joint provided which does not exist. "
1106+
"This is not supported.",
10941107
link_name.c_str());
10951108
return false;
10961109
}
10971110

1098-
if (joint_exists)
1111+
if ((link_exists && cmd->getJoint() && !joint_exists))
10991112
{
1100-
CONSOLE_BRIDGE_logWarn("Tried to add link (%s) with a joint that already exists.", joint_name.c_str());
1113+
CONSOLE_BRIDGE_logWarn("Tried to add link (%s) which already exists with a joint provided which does not exist. "
1114+
"This is not supported.",
1115+
link_name.c_str());
11011116
return false;
11021117
}
11031118

@@ -1106,6 +1121,45 @@ bool Environment::applyAddCommand(AddLinkCommand::ConstPtr cmd)
11061121
if (!scene_graph_->addLink(*cmd->getLink(), true))
11071122
return false;
11081123
}
1124+
else if (link_exists && joint_exists)
1125+
{ // A link and joint pair is being replaced
1126+
tesseract_scene_graph::Link::ConstPtr orig_link = getLink(link_name);
1127+
tesseract_scene_graph::Joint::ConstPtr orig_joint = getJoint(joint_name);
1128+
1129+
if (orig_joint->child_link_name != orig_link->getName())
1130+
{
1131+
CONSOLE_BRIDGE_logWarn("Tried to replace link (%s) and joint (%s) which are currently not linked. This is not "
1132+
"supported.",
1133+
link_name.c_str(),
1134+
joint_name.c_str());
1135+
return false;
1136+
}
1137+
1138+
if (!scene_graph_->addLink(*cmd->getLink(), true))
1139+
return false;
1140+
1141+
if (!scene_graph_->removeJoint(joint_name))
1142+
{
1143+
// Replace with original link
1144+
if (!scene_graph_->addLink(*orig_link, true))
1145+
throw std::runtime_error("Environment: Failed to replace link and joint and reset to original state.");
1146+
1147+
return false;
1148+
}
1149+
1150+
if (!scene_graph_->addJoint(*cmd->getJoint()))
1151+
{
1152+
// Replace with original link
1153+
if (!scene_graph_->addLink(*orig_link, true))
1154+
throw std::runtime_error("Environment: Failed to replace link and joint reset to original state.");
1155+
1156+
// Replace with original link
1157+
if (!scene_graph_->addJoint(*orig_joint))
1158+
throw std::runtime_error("Environment: Failed to replace link and joint and reset to original state.");
1159+
1160+
return false;
1161+
}
1162+
}
11091163
else if (!link_exists && !cmd->getJoint())
11101164
{ // Add a new link is being added attached to the world
11111165
std::string joint_name = "joint_" + link_name;

tesseract_environment/src/ofkt/ofkt_state_solver.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,13 +328,20 @@ void OFKTStateSolver::onEnvironmentChanged(const Commands& commands)
328328

329329
// These check are handled by the environment but just as a precaution adding asserts here
330330
assert(!(link_exists && !cmd.replaceAllowed()));
331-
assert(!(link_exists && cmd.getJoint()));
332-
assert(!joint_exists);
331+
assert(!(joint_exists && !cmd.replaceAllowed()));
332+
assert(!(link_exists && cmd.getJoint() && !joint_exists));
333+
assert(!(!link_exists && joint_exists));
333334

334335
if (link_exists && !cmd.getJoint())
335336
{ // A link is being replaced there is nothing to be done
336337
break;
337338
}
339+
else if (link_exists && joint_exists)
340+
{ // A link and joint is being replaced
341+
assert(!((cmd.getLink() != nullptr) && (cmd.getJoint() != nullptr) &&
342+
(cmd.getJoint()->child_link_name != cmd.getLink()->getName())));
343+
replaceJointHelper(new_kinematic_joints, cmd.getJoint());
344+
}
338345
else
339346
{ // A new joint and link was added
340347
const tesseract_scene_graph::Joint::ConstPtr& joint = cmd.getJoint();

tesseract_environment/test/tesseract_environment_unit.cpp

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,6 +1690,85 @@ void runApplyCommandsStateSolverCompareTest()
16901690
runGetLinkTransformsTest(*base_env);
16911691
runGetLinkTransformsTest(*compare_env);
16921692
}
1693+
{ // Replace link and joint which is allowed
1694+
// Get the environment
1695+
auto base_env = getEnvironment<KDLStateSolver>();
1696+
auto compare_env = getEnvironment<S>();
1697+
1698+
Link link_1("link_1");
1699+
Joint joint_1("joint_a1");
1700+
joint_1.parent_to_joint_origin_transform.translation()(0) = 1.25;
1701+
joint_1.parent_link_name = "base_link";
1702+
joint_1.child_link_name = "link_1";
1703+
joint_1.type = JointType::FIXED;
1704+
1705+
Commands commands{ std::make_shared<AddLinkCommand>(link_1, joint_1, true) };
1706+
EXPECT_TRUE(base_env->applyCommands(commands));
1707+
EXPECT_TRUE(compare_env->applyCommands(commands));
1708+
runCompareStateSolvers(*base_env->getStateSolver(), *compare_env->getStateSolver());
1709+
runGetLinkTransformsTest(*base_env);
1710+
runGetLinkTransformsTest(*compare_env);
1711+
}
1712+
1713+
{ // Replace link and joint which is not allowed
1714+
// Get the environment
1715+
auto base_env = getEnvironment<KDLStateSolver>();
1716+
auto compare_env = getEnvironment<S>();
1717+
1718+
Link link_1("link_1");
1719+
Joint joint_1("joint_a1");
1720+
joint_1.parent_to_joint_origin_transform.translation()(0) = 1.25;
1721+
joint_1.parent_link_name = "base_link";
1722+
joint_1.child_link_name = "link_1";
1723+
joint_1.type = JointType::FIXED;
1724+
1725+
Commands commands{ std::make_shared<AddLinkCommand>(link_1, joint_1, false) };
1726+
EXPECT_FALSE(base_env->applyCommands(commands));
1727+
EXPECT_FALSE(compare_env->applyCommands(commands));
1728+
runCompareStateSolvers(*base_env->getStateSolver(), *compare_env->getStateSolver());
1729+
runGetLinkTransformsTest(*base_env);
1730+
runGetLinkTransformsTest(*compare_env);
1731+
}
1732+
1733+
{ // Replace joint wich exist but the link does not which should fail
1734+
// Get the environment
1735+
auto base_env = getEnvironment<KDLStateSolver>();
1736+
auto compare_env = getEnvironment<S>();
1737+
1738+
Link link_1("link_2_does_not_exist");
1739+
Joint joint_1("joint_a1");
1740+
joint_1.parent_to_joint_origin_transform.translation()(0) = 1.25;
1741+
joint_1.parent_link_name = "base_link";
1742+
joint_1.child_link_name = "link_2_does_not_exist";
1743+
joint_1.type = JointType::FIXED;
1744+
1745+
Commands commands{ std::make_shared<AddLinkCommand>(link_1, joint_1, true) };
1746+
EXPECT_FALSE(base_env->applyCommands(commands));
1747+
EXPECT_FALSE(compare_env->applyCommands(commands));
1748+
runCompareStateSolvers(*base_env->getStateSolver(), *compare_env->getStateSolver());
1749+
runGetLinkTransformsTest(*base_env);
1750+
runGetLinkTransformsTest(*compare_env);
1751+
}
1752+
1753+
{ // Replace link and joint which is not allowed but they are not currently linked
1754+
// Get the environment
1755+
auto base_env = getEnvironment<KDLStateSolver>();
1756+
auto compare_env = getEnvironment<S>();
1757+
1758+
Link link_1("link_2");
1759+
Joint joint_1("joint_a1");
1760+
joint_1.parent_to_joint_origin_transform.translation()(0) = 1.25;
1761+
joint_1.parent_link_name = "base_link";
1762+
joint_1.child_link_name = "link_2";
1763+
joint_1.type = JointType::FIXED;
1764+
1765+
Commands commands{ std::make_shared<AddLinkCommand>(link_1, joint_1, false) };
1766+
EXPECT_FALSE(base_env->applyCommands(commands));
1767+
EXPECT_FALSE(compare_env->applyCommands(commands));
1768+
runCompareStateSolvers(*base_env->getStateSolver(), *compare_env->getStateSolver());
1769+
runGetLinkTransformsTest(*base_env);
1770+
runGetLinkTransformsTest(*compare_env);
1771+
}
16931772

16941773
{ // Replace link which is not allowed
16951774
// Get the environment

0 commit comments

Comments
 (0)