예제 #1
0
TEST(FK, OneRobot)
{
    static const std::string MODEL2 =
        "<?xml version=\"1.0\" ?>"
        "<robot name=\"one_robot\">"
        "<link name=\"base_link\">"
        "  <inertial>"
        "    <mass value=\"2.81\"/>"
        "    <origin rpy=\"0 0 0\" xyz=\"0.0 0.0 .0\"/>"
        "    <inertia ixx=\"0.1\" ixy=\"-0.2\" ixz=\"0.5\" iyy=\"-.09\" iyz=\"1\" izz=\"0.101\"/>"
        "  </inertial>"
        "  <collision name=\"my_collision\">"
        "    <origin rpy=\"0 0 0\" xyz=\"0 0 0\"/>"
        "    <geometry>"
        "      <box size=\"1 2 1\" />"
        "    </geometry>"
        "  </collision>"
        "  <visual>"
        "    <origin rpy=\"0 0 0\" xyz=\"0.0 0 0\"/>"
        "    <geometry>"
        "      <box size=\"1 2 1\" />"
        "    </geometry>"
        "  </visual>"
        "</link>"
        "<joint name=\"joint_a\" type=\"continuous\">"
        "   <axis xyz=\"0 0 1\"/>"
        "   <parent link=\"base_link\"/>"
        "   <child link=\"link_a\"/>"
        "   <origin rpy=\" 0.0 0 0 \" xyz=\"0.0 0 0 \"/>"
        "</joint>"
        "<link name=\"link_a\">"
        "  <inertial>"
        "    <mass value=\"1.0\"/>"
        "    <origin rpy=\"0 0 0\" xyz=\"0.0 0.0 .0\"/>"
        "    <inertia ixx=\"0.1\" ixy=\"-0.2\" ixz=\"0.5\" iyy=\"-.09\" iyz=\"1\" izz=\"0.101\"/>"
        "  </inertial>"
        "  <collision>"
        "    <origin rpy=\"0 0 0\" xyz=\"0 0 0\"/>"
        "    <geometry>"
        "      <box size=\"1 2 1\" />"
        "    </geometry>"
        "  </collision>"
        "  <visual>"
        "    <origin rpy=\"0 0 0\" xyz=\"0.0 0 0\"/>"
        "    <geometry>"
        "      <box size=\"1 2 1\" />"
        "    </geometry>"
        "  </visual>"
        "</link>"
        "<joint name=\"joint_b\" type=\"fixed\">"
        "  <parent link=\"link_a\"/>"
        "  <child link=\"link_b\"/>"
        "  <origin rpy=\" 0.0 -0.42 0 \" xyz=\"0.0 0.5 0 \"/>"
        "</joint>"
        "<link name=\"link_b\">"
        "  <inertial>"
        "    <mass value=\"1.0\"/>"
        "    <origin rpy=\"0 0 0\" xyz=\"0.0 0.0 .0\"/>"
        "    <inertia ixx=\"0.1\" ixy=\"-0.2\" ixz=\"0.5\" iyy=\"-.09\" iyz=\"1\" izz=\"0.101\"/>"
        "  </inertial>"
        "  <collision>"
        "    <origin rpy=\"0 0 0\" xyz=\"0 0 0\"/>"
        "    <geometry>"
        "      <box size=\"1 2 1\" />"
        "    </geometry>"
        "  </collision>"
        "  <visual>"
        "    <origin rpy=\"0 0 0\" xyz=\"0.0 0 0\"/>"
        "    <geometry>"
        "      <box size=\"1 2 1\" />"
        "    </geometry>"
        "  </visual>"
        "</link>"
        "  <joint name=\"joint_c\" type=\"prismatic\">"
        "    <axis xyz=\"1 0 0\"/>"
        "    <limit effort=\"100.0\" lower=\"0.0\" upper=\"0.09\" velocity=\"0.2\"/>"
        "    <safety_controller k_position=\"20.0\" k_velocity=\"500.0\" soft_lower_limit=\"0.0\" soft_upper_limit=\"0.089\"/>"
        "    <parent link=\"link_b\"/>"
        "    <child link=\"link_c\"/>"
        "    <origin rpy=\" 0.0 0.42 0.0 \" xyz=\"0.0 -0.1 0 \"/>"
        "  </joint>"
        "<link name=\"link_c\">"
        "  <inertial>"
        "    <mass value=\"1.0\"/>"
        "    <origin rpy=\"0 0 0\" xyz=\"0.0 0 .0\"/>"
        "    <inertia ixx=\"0.1\" ixy=\"-0.2\" ixz=\"0.5\" iyy=\"-.09\" iyz=\"1\" izz=\"0.101\"/>"
        "  </inertial>"
        "  <collision>"
        "    <origin rpy=\"0 0 0\" xyz=\"0 0 0\"/>"
        "    <geometry>"
        "      <box size=\"1 2 1\" />"
        "    </geometry>"
        "  </collision>"
        "  <visual>"
        "    <origin rpy=\"0 0 0\" xyz=\"0.0 0 0\"/>"
        "    <geometry>"
        "      <box size=\"1 2 1\" />"
        "    </geometry>"
        "  </visual>"
        "</link>"
        "</robot>";

    static const std::string MODEL2_INFO =
        "Model one_robot in frame odom_combined, of dimension 5\n"
        "Joint values bounds: \n"
        "   base_joint/x [DBL_MIN, DBL_MAX]\n"
        "   base_joint/y [DBL_MIN, DBL_MAX]\n"
        "   base_joint/theta [-3.14159, 3.14159]\n"
        "   joint_a [-3.14159, 3.14159]\n"
        "   joint_c [0.00000, 0.08900]\n"
        "\n"
        "Available groups: \n"
        "   base_from_base_to_tip (of dimension 4):\n"
        "     joints:\n"
        "      base_joint\n"
        "      joint_a\n"
        "     links:\n"
        "      base_link\n"
        "      link_a\n"
        "      link_b\n"
        "     roots:\n"
        "      base_joint\n"
        "   base_from_joints (of dimension 5):\n"
        "     joints:\n"
        "      base_joint\n"
        "      joint_a\n"
        "      joint_c\n"
        "     links:\n"
        "      base_link\n"
        "      link_a\n"
        "      link_c\n"
        "     roots:\n"
        "      base_joint\n"
        "   base_with_subgroups (of dimension 5):\n"
        "     joints:\n"
        "      base_joint\n"
        "      joint_a\n"
        "      joint_c\n"
        "     links:\n"
        "      base_link\n"
        "      link_a\n"
        "      link_b\n"
        "      link_c\n"
        "     roots:\n"
        "      base_joint";

    static const std::string SMODEL2 =
        "<?xml version=\"1.0\" ?>"
        "<robot name=\"one_robot\">"
        "<virtual_joint name=\"base_joint\" child_link=\"base_link\" parent_frame=\"odom_combined\" type=\"planar\"/>"
        "<group name=\"base_from_joints\">"
        "<joint name=\"base_joint\"/>"
        "<joint name=\"joint_a\"/>"
        "<joint name=\"joint_c\"/>"
        "</group>"
        "<group name=\"base_with_subgroups\">"
        "<group name=\"base_from_base_to_tip\"/>"
        "<joint name=\"joint_c\"/>"
        "</group>"
        "<group name=\"base_from_base_to_tip\">"
        "<chain base_link=\"base_link\" tip_link=\"link_b\"/>"
        "<joint name=\"base_joint\"/>"
        "</group>"
        "<group name=\"base_with_bad_subgroups\">"
        "<group name=\"error\"/>"
        "</group>"
        "</robot>";

    boost::shared_ptr<urdf::ModelInterface> urdfModel = urdf::parseURDF(MODEL2);

    boost::shared_ptr<srdf::Model> srdfModel(new srdf::Model());
    srdfModel->initString(*urdfModel, SMODEL2);

    planning_models::KinematicModelPtr model(new planning_models::KinematicModel(urdfModel, srdfModel));

    //testing that the two planning groups are the same
    const planning_models::KinematicModel::JointModelGroup* g_one = model->getJointModelGroup("base_from_joints");
    const planning_models::KinematicModel::JointModelGroup* g_two = model->getJointModelGroup("base_from_base_to_tip");
    const planning_models::KinematicModel::JointModelGroup* g_three = model->getJointModelGroup("base_with_subgroups");
    const planning_models::KinematicModel::JointModelGroup* g_four = model->getJointModelGroup("base_with_bad_subgroups");

    ASSERT_TRUE(g_one != NULL);
    ASSERT_TRUE(g_two != NULL);
    ASSERT_TRUE(g_three != NULL);
    ASSERT_TRUE(g_four == NULL);

    //joint_b is a fixed joint, so no one should have it
    ASSERT_EQ(g_one->getJointModelNames().size(), 3);
    ASSERT_EQ(g_two->getJointModelNames().size(), 2);
    ASSERT_EQ(g_three->getJointModelNames().size(), 3);

    //only the links in between the joints, and the children of the leafs
    ASSERT_EQ(g_one->getLinkModelNames().size(), 3);
    //g_two only has three links
    ASSERT_EQ(g_two->getLinkModelNames().size(), 3);
    ASSERT_EQ(g_three->getLinkModelNames().size(), 4);

    std::vector<std::string> jmn = g_one->getJointModelNames();
    std::sort(jmn.begin(), jmn.end());
    EXPECT_EQ(jmn[0],"base_joint");
    EXPECT_EQ(jmn[1],"joint_a");
    EXPECT_EQ(jmn[2],"joint_c");
    jmn = g_two->getJointModelNames();
    std::sort(jmn.begin(), jmn.end());
    EXPECT_EQ(jmn[0],"base_joint");
    EXPECT_EQ(jmn[1],"joint_a");
    jmn = g_three->getJointModelNames();
    std::sort(jmn.begin(), jmn.end());
    EXPECT_EQ(jmn[0],"base_joint");
    EXPECT_EQ(jmn[1],"joint_a");
    EXPECT_EQ(jmn[2],"joint_c");

    //but they should have the same links to be updated
    ASSERT_EQ(g_one->getUpdatedLinkModels().size(), 4);
    ASSERT_EQ(g_two->getUpdatedLinkModels().size(), 4);
    ASSERT_EQ(g_three->getUpdatedLinkModels().size(), 4);

    EXPECT_EQ(g_one->getUpdatedLinkModels()[0]->getName(),"base_link");
    EXPECT_EQ(g_one->getUpdatedLinkModels()[1]->getName(),"link_a");
    EXPECT_EQ(g_one->getUpdatedLinkModels()[2]->getName(),"link_b");
    EXPECT_EQ(g_one->getUpdatedLinkModels()[3]->getName(),"link_c");

    EXPECT_EQ(g_two->getUpdatedLinkModels()[0]->getName(),"base_link");
    EXPECT_EQ(g_two->getUpdatedLinkModels()[1]->getName(),"link_a");
    EXPECT_EQ(g_two->getUpdatedLinkModels()[2]->getName(),"link_b");
    EXPECT_EQ(g_two->getUpdatedLinkModels()[3]->getName(),"link_c");

    EXPECT_EQ(g_three->getUpdatedLinkModels()[0]->getName(),"base_link");
    EXPECT_EQ(g_three->getUpdatedLinkModels()[1]->getName(),"link_a");
    EXPECT_EQ(g_three->getUpdatedLinkModels()[2]->getName(),"link_b");
    EXPECT_EQ(g_three->getUpdatedLinkModels()[3]->getName(),"link_c");

    //bracketing so the state gets destroyed before we bring down the model

    planning_models::KinematicState state(model);

    EXPECT_EQ((unsigned int)5, state.getVariableCount());

    state.setToDefaultValues();

    std::map<std::string, double> joint_values;
    joint_values["base_joint/x"]=1.0;
    joint_values["base_joint/y"]=1.0;
    joint_values["base_joint/theta"]=0.5;
    joint_values["joint_a"] = -0.5;
    joint_values["joint_c"] = 0.1;
    state.getJointStateGroup("base_from_joints")->setStateValues(joint_values);

    //double param[5] = { 1, 1, 0.5, -0.5, 0.1 };
    //model->getGroup("base")->computeTransforms(param);

    std::stringstream ss0;
    model->printModelInfo(ss0);
    EXPECT_TRUE(sameStringIgnoringWS(MODEL2_INFO, ss0.str())) << MODEL2_INFO << "\n" << ss0.str();

    std::stringstream ss1;
    state.printTransforms(ss1);

    //make sure it works the same way for the whole robot
    state.setStateValues(joint_values);
    std::stringstream ss2;
    state.printTransforms(ss2);

    EXPECT_EQ(ss1.str(), ss2.str());
    
    EXPECT_NEAR(1.0, state.getLinkState("base_link")->getGlobalLinkTransform().translation().x(), 1e-5);
    EXPECT_NEAR(1.0, state.getLinkState("base_link")->getGlobalLinkTransform().translation().y(), 1e-5);
    EXPECT_NEAR(0.0, state.getLinkState("base_link")->getGlobalLinkTransform().translation().z(), 1e-5);
    EXPECT_NEAR(0.0, Eigen::Quaterniond(state.getLinkState("base_link")->getGlobalLinkTransform().rotation()).x(), 1e-5);
    EXPECT_NEAR(0.0, Eigen::Quaterniond(state.getLinkState("base_link")->getGlobalLinkTransform().rotation()).y(), 1e-5);
    EXPECT_NEAR(0.247404, Eigen::Quaterniond(state.getLinkState("base_link")->getGlobalLinkTransform().rotation()).z(), 1e-5);
    EXPECT_NEAR(0.968912, Eigen::Quaterniond(state.getLinkState("base_link")->getGlobalLinkTransform().rotation()).w(), 1e-5);

    EXPECT_NEAR(1.0, state.getLinkState("link_a")->getGlobalLinkTransform().translation().x(), 1e-5);
    EXPECT_NEAR(1.0, state.getLinkState("link_a")->getGlobalLinkTransform().translation().y(), 1e-5);
    EXPECT_NEAR(0.0, state.getLinkState("link_a")->getGlobalLinkTransform().translation().z(), 1e-5);
    EXPECT_NEAR(0.0, Eigen::Quaterniond(state.getLinkState("link_a")->getGlobalLinkTransform().rotation()).x(), 1e-5);
    EXPECT_NEAR(0.0, Eigen::Quaterniond(state.getLinkState("link_a")->getGlobalLinkTransform().rotation()).y(), 1e-5);
    EXPECT_NEAR(0.0, Eigen::Quaterniond(state.getLinkState("link_a")->getGlobalLinkTransform().rotation()).z(), 1e-5);
    EXPECT_NEAR(1.0, Eigen::Quaterniond(state.getLinkState("link_a")->getGlobalLinkTransform().rotation()).w(), 1e-5);

    EXPECT_NEAR(1.0, state.getLinkState("link_b")->getGlobalLinkTransform().translation().x(), 1e-5);
    EXPECT_NEAR(1.5, state.getLinkState("link_b")->getGlobalLinkTransform().translation().y(), 1e-5);
    EXPECT_NEAR(0.0, state.getLinkState("link_b")->getGlobalLinkTransform().translation().z(), 1e-5);
    EXPECT_NEAR(0.0, Eigen::Quaterniond(state.getLinkState("link_b")->getGlobalLinkTransform().rotation()).x(), 1e-5);
    EXPECT_NEAR(-0.2084598, Eigen::Quaterniond(state.getLinkState("link_b")->getGlobalLinkTransform().rotation()).y(), 1e-5);
    EXPECT_NEAR(0.0, Eigen::Quaterniond(state.getLinkState("link_b")->getGlobalLinkTransform().rotation()).z(), 1e-5);
    EXPECT_NEAR(0.97803091, Eigen::Quaterniond(state.getLinkState("link_b")->getGlobalLinkTransform().rotation()).w(), 1e-5);

    EXPECT_NEAR(1.1, state.getLinkState("link_c")->getGlobalLinkTransform().translation().x(), 1e-5);
    EXPECT_NEAR(1.4, state.getLinkState("link_c")->getGlobalLinkTransform().translation().y(), 1e-5);
    EXPECT_NEAR(0.0, state.getLinkState("link_c")->getGlobalLinkTransform().translation().z(), 1e-5);
    EXPECT_NEAR(0.0, Eigen::Quaterniond(state.getLinkState("link_c")->getGlobalLinkTransform().rotation()).x(), 1e-5);
    EXPECT_NEAR(0.0, Eigen::Quaterniond(state.getLinkState("link_c")->getGlobalLinkTransform().rotation()).y(), 1e-5);
    EXPECT_NEAR(0.0, Eigen::Quaterniond(state.getLinkState("link_c")->getGlobalLinkTransform().rotation()).z(), 1e-5);
    EXPECT_NEAR(1.0, Eigen::Quaterniond(state.getLinkState("link_c")->getGlobalLinkTransform().rotation()).w(), 1e-5);

    //bonus bounds lookup test
    std::vector<std::string> jn;
    jn.push_back("base_joint");
    EXPECT_TRUE(state.satisfiesBounds(jn));

    jn.push_back("monkey");
    EXPECT_FALSE(state.satisfiesBounds(jn));

    std::map<std::string, double> upd_a;
    upd_a["joint_a"] = 0.2;
    state.setStateValues(upd_a);
    EXPECT_TRUE(state.satisfiesBounds("joint_a"));
    EXPECT_NEAR(state.getJointState("joint_a")->getVariableValues()[0], 0.2, 1e-3);
    state.enforceBounds();
    EXPECT_NEAR(state.getJointState("joint_a")->getVariableValues()[0], 0.2, 1e-3);
    
    upd_a["joint_a"] = 3.2;
    state.setStateValues(upd_a);
    EXPECT_TRUE(state.satisfiesBounds("joint_a"));
    EXPECT_NEAR(state.getJointState("joint_a")->getVariableValues()[0], 3.2, 1e-3);
    state.enforceBounds();
    EXPECT_NEAR(state.getJointState("joint_a")->getVariableValues()[0], -3.083185, 1e-3);
    EXPECT_TRUE(state.satisfiesBounds("joint_a"));
}
TEST(FK, OneRobot)
{
  static const std::string MODEL2 = 
    "<?xml version=\"1.0\" ?>" 
    "<robot name=\"one_robot\">"
    "<link name=\"base_link\">"
    "  <inertial>"
    "    <mass value=\"2.81\"/>"
    "    <origin rpy=\"0 0 0\" xyz=\"0.0 0.0 .0\"/>"
    "    <inertia ixx=\"0.1\" ixy=\"-0.2\" ixz=\"0.5\" iyy=\"-.09\" iyz=\"1\" izz=\"0.101\"/>"
    "  </inertial>"
    "  <collision name=\"my_collision\">"
    "    <origin rpy=\"0 0 0\" xyz=\"0 0 0\"/>"
    "    <geometry>"
    "      <box size=\"1 2 1\" />"
    "    </geometry>"
    "  </collision>"
    "  <visual>"
    "    <origin rpy=\"0 0 0\" xyz=\"0.0 0 0\"/>"
    "    <geometry>"
    "      <box size=\"1 2 1\" />"
    "    </geometry>"
    "  </visual>"
    "</link>"
    "<joint name=\"joint_a\" type=\"continuous\">"
    "   <axis xyz=\"0 0 1\"/>"
    "   <parent link=\"base_link\"/>"
    "   <child link=\"link_a\"/>"
    "   <origin rpy=\" 0.0 0 0 \" xyz=\"0.0 0 0 \"/>"
    "</joint>"
    "<link name=\"link_a\">"
    "  <inertial>"
    "    <mass value=\"1.0\"/>"
    "    <origin rpy=\"0 0 0\" xyz=\"0.0 0.0 .0\"/>"
    "    <inertia ixx=\"0.1\" ixy=\"-0.2\" ixz=\"0.5\" iyy=\"-.09\" iyz=\"1\" izz=\"0.101\"/>"
    "  </inertial>"
    "  <collision>"
    "    <origin rpy=\"0 0 0\" xyz=\"0 0 0\"/>"
    "    <geometry>"
    "      <box size=\"1 2 1\" />"
    "    </geometry>"
    "  </collision>"
    "  <visual>"
    "    <origin rpy=\"0 0 0\" xyz=\"0.0 0 0\"/>"
    "    <geometry>"
    "      <box size=\"1 2 1\" />"
    "    </geometry>"
    "  </visual>"
    "</link>"
    "<joint name=\"joint_b\" type=\"fixed\">"
    "  <parent link=\"link_a\"/>"
    "  <child link=\"link_b\"/>"
    "  <origin rpy=\" 0.0 -0.42 0 \" xyz=\"0.0 0.5 0 \"/>"
    "</joint>"
    "<link name=\"link_b\">"
    "  <inertial>"
    "    <mass value=\"1.0\"/>"
    "    <origin rpy=\"0 0 0\" xyz=\"0.0 0.0 .0\"/>"
    "    <inertia ixx=\"0.1\" ixy=\"-0.2\" ixz=\"0.5\" iyy=\"-.09\" iyz=\"1\" izz=\"0.101\"/>"
    "  </inertial>"
    "  <collision>"
    "    <origin rpy=\"0 0 0\" xyz=\"0 0 0\"/>"
    "    <geometry>"
    "      <box size=\"1 2 1\" />"
    "    </geometry>"
    "  </collision>"
    "  <visual>"
    "    <origin rpy=\"0 0 0\" xyz=\"0.0 0 0\"/>"
    "    <geometry>"
    "      <box size=\"1 2 1\" />"
    "    </geometry>"
    "  </visual>"
    "</link>"
    "  <joint name=\"joint_c\" type=\"prismatic\">"
    "    <axis xyz=\"1 0 0\"/>"
    "    <limit effort=\"100.0\" lower=\"0.0\" upper=\"0.09\" velocity=\"0.2\"/>"
    "    <safety_controller k_position=\"20.0\" k_velocity=\"500.0\" soft_lower_limit=\"0.0\" soft_upper_limit=\"0.089\"/>"
    "    <parent link=\"link_b\"/>"
    "    <child link=\"link_c\"/>"
    "    <origin rpy=\" 0.0 0.42 0.0 \" xyz=\"0.0 -0.1 0 \"/>"
    "  </joint>"
    "<link name=\"link_c\">"
    "  <inertial>"
    "    <mass value=\"1.0\"/>"
    "    <origin rpy=\"0 0 0\" xyz=\"0.0 0 .0\"/>"
    "    <inertia ixx=\"0.1\" ixy=\"-0.2\" ixz=\"0.5\" iyy=\"-.09\" iyz=\"1\" izz=\"0.101\"/>"
    "  </inertial>"
    "  <collision>"
    "    <origin rpy=\"0 0 0\" xyz=\"0 0 0\"/>"
    "    <geometry>"
    "      <box size=\"1 2 1\" />"
    "    </geometry>"
    "  </collision>"
    "  <visual>"
    "    <origin rpy=\"0 0 0\" xyz=\"0.0 0 0\"/>"
    "    <geometry>"
    "      <box size=\"1 2 1\" />"
    "    </geometry>"
    "  </visual>"
    "</link>"
    "</robot>";
    
  static const std::string MODEL2_INFO = 
    "Complete model state dimension = 5\n"
    "State bounds: [-3.14159, 3.14159] [-DBL_MAX, DBL_MAX] [-DBL_MAX, DBL_MAX] [-3.14159, 3.14159] [0.00000, 0.08900]\n"
    "Root joint : base_joint \n"
    "Available groups: base_from_base_to_tip base_from_joints base_with_subgroups \n"
    "Group base_from_base_to_tip has 1 roots: base_joint  \n"
    "Group base_from_joints has 1 roots: base_joint \n"
    "Group base_with_subgroups has 1 roots: base_joint \n";
    

  urdf::Model urdfModel;
  urdfModel.initString(MODEL2);

  std::vector<std::string> gc_joints;
  gc_joints.push_back("base_joint");
  gc_joints.push_back("joint_a");
  gc_joints.push_back("joint_c");
  std::vector<std::string> subgroups;
  std::vector<planning_models::KinematicModel::GroupConfig> gcs;
  gcs.push_back(planning_models::KinematicModel::GroupConfig("base_from_joints", gc_joints, subgroups));

  //defining this in the list before the actual subgroup to make sure that works
  std::vector<std::string> extra_joint;
  extra_joint.push_back("joint_c");
  subgroups.push_back("base_from_base_to_tip");
  gcs.push_back(planning_models::KinematicModel::GroupConfig("base_with_subgroups", extra_joint, subgroups));
    
  //not making this all the way to joint_c intentionally
  gcs.push_back(planning_models::KinematicModel::GroupConfig("base_from_base_to_tip","odom_combined","link_b"));

  //now adding a fake one
  subgroups.push_back("monkey_group");
  gcs.push_back(planning_models::KinematicModel::GroupConfig("base_with_bad_subgroups", extra_joint, subgroups));

  std::vector<planning_models::KinematicModel::MultiDofConfig> multi_dof_configs;
  planning_models::KinematicModel::MultiDofConfig config("base_joint");
  config.type = "Planar";
  config.parent_frame_id = "odom_combined";
  config.child_frame_id = "base_link";
  multi_dof_configs.push_back(config);
    
  planning_models::KinematicModel* model = new planning_models::KinematicModel(urdfModel,gcs,multi_dof_configs);
    
  //testing that the two planning groups are the same
  const planning_models::KinematicModel::JointModelGroup* g_one = model->getModelGroup("base_from_joints");
  const planning_models::KinematicModel::JointModelGroup* g_two = model->getModelGroup("base_from_base_to_tip");
  const planning_models::KinematicModel::JointModelGroup* g_three = model->getModelGroup("base_with_subgroups");
  const planning_models::KinematicModel::JointModelGroup* g_four = model->getModelGroup("base_with_bad_subgroups");

  ASSERT_TRUE(g_one != NULL);
  ASSERT_TRUE(g_two != NULL);
  ASSERT_TRUE(g_three != NULL);
  ASSERT_TRUE(g_four == NULL);

  //joint_b is a fixed joint, so no one should have it
  ASSERT_EQ(g_one->getJointModelNames().size(), 3); 
  ASSERT_EQ(g_two->getJointModelNames().size(), 2); 
  ASSERT_EQ(g_three->getJointModelNames().size(), 3); 

  //only the links in between the joints, and the children of the leafs
  ASSERT_EQ(g_one->getGroupLinkModels().size(), 4);
  //g_two only has three links
  ASSERT_EQ(g_two->getGroupLinkModels().size(), 3);
  ASSERT_EQ(g_three->getGroupLinkModels().size(), 4);
    
  EXPECT_EQ(g_one->getJointModelNames()[0],"base_joint");
  EXPECT_EQ(g_one->getJointModelNames()[1],"joint_a");
  EXPECT_EQ(g_one->getJointModelNames()[2],"joint_c");
  EXPECT_EQ(g_two->getJointModelNames()[0],"base_joint");
  EXPECT_EQ(g_two->getJointModelNames()[1],"joint_a");
  EXPECT_EQ(g_three->getJointModelNames()[0],"base_joint");
  EXPECT_EQ(g_three->getJointModelNames()[1],"joint_a");
  EXPECT_EQ(g_three->getJointModelNames()[2],"joint_c");

  //but they should have the same links to be updated
  ASSERT_EQ(g_one->getUpdatedLinkModels().size(), 4);
  ASSERT_EQ(g_two->getUpdatedLinkModels().size(), 4);
  ASSERT_EQ(g_three->getUpdatedLinkModels().size(), 4);

  EXPECT_EQ(g_one->getUpdatedLinkModels()[0]->getName(),"base_link");
  EXPECT_EQ(g_one->getUpdatedLinkModels()[1]->getName(),"link_a");
  EXPECT_EQ(g_one->getUpdatedLinkModels()[2]->getName(),"link_b");
  EXPECT_EQ(g_one->getUpdatedLinkModels()[3]->getName(),"link_c");

  EXPECT_EQ(g_two->getUpdatedLinkModels()[0]->getName(),"base_link");
  EXPECT_EQ(g_two->getUpdatedLinkModels()[1]->getName(),"link_a");
  EXPECT_EQ(g_two->getUpdatedLinkModels()[2]->getName(),"link_b");
  EXPECT_EQ(g_two->getUpdatedLinkModels()[3]->getName(),"link_c");

  EXPECT_EQ(g_three->getUpdatedLinkModels()[0]->getName(),"base_link");
  EXPECT_EQ(g_three->getUpdatedLinkModels()[1]->getName(),"link_a");
  EXPECT_EQ(g_three->getUpdatedLinkModels()[2]->getName(),"link_b");
  EXPECT_EQ(g_three->getUpdatedLinkModels()[3]->getName(),"link_c");

  //bracketing so the state gets destroyed before we bring down the model
  {
    planning_models::KinematicState state(model);
    
    EXPECT_EQ((unsigned int)5, state.getDimension());

    state.setKinematicStateToDefault();

    std::map<std::string, double> joint_values;
    joint_values["planar_x"]=1.0;
    joint_values["planar_y"]=1.0;
    joint_values["planar_th"]=0.5;
    joint_values["joint_a"] = -0.5;
    joint_values["joint_c"] = 0.1;
    state.getJointStateGroup("base_from_joints")->setKinematicState(joint_values);
    
    //double param[5] = { 1, 1, 0.5, -0.5, 0.1 };
    //model->getGroup("base")->computeTransforms(param);
    
    std::stringstream ss1;
    state.printStateInfo(ss1);
    EXPECT_TRUE(sameStringIgnoringWS(MODEL2_INFO, ss1.str())) << MODEL2_INFO << "\n" << ss1.str();
    state.printTransforms(ss1);
    
    //make sure it works the same way for the whole robot
    state.setKinematicState(joint_values);
    std::stringstream ss2;
    state.printStateInfo(ss2);
    state.printTransforms(ss2);
    
    EXPECT_EQ(ss1.str(), ss2.str());
    
    EXPECT_NEAR(1.0, state.getLinkState("base_link")->getGlobalLinkTransform().getOrigin().x(), 1e-5);
    EXPECT_NEAR(1.0, state.getLinkState("base_link")->getGlobalLinkTransform().getOrigin().y(), 1e-5);
    EXPECT_NEAR(0.0, state.getLinkState("base_link")->getGlobalLinkTransform().getOrigin().z(), 1e-5);
    EXPECT_NEAR(0.0, state.getLinkState("base_link")->getGlobalLinkTransform().getRotation().x(), 1e-5);
    EXPECT_NEAR(0.0, state.getLinkState("base_link")->getGlobalLinkTransform().getRotation().y(), 1e-5);
    EXPECT_NEAR(0.247404, state.getLinkState("base_link")->getGlobalLinkTransform().getRotation().z(), 1e-5);
    EXPECT_NEAR(0.968912, state.getLinkState("base_link")->getGlobalLinkTransform().getRotation().w(), 1e-5);
    
    EXPECT_NEAR(1.0, state.getLinkState("link_a")->getGlobalLinkTransform().getOrigin().x(), 1e-5);
    EXPECT_NEAR(1.0, state.getLinkState("link_a")->getGlobalLinkTransform().getOrigin().y(), 1e-5);
    EXPECT_NEAR(0.0, state.getLinkState("link_a")->getGlobalLinkTransform().getOrigin().z(), 1e-5);
    EXPECT_NEAR(0.0, state.getLinkState("link_a")->getGlobalLinkTransform().getRotation().x(), 1e-5);
    EXPECT_NEAR(0.0, state.getLinkState("link_a")->getGlobalLinkTransform().getRotation().y(), 1e-5);
    EXPECT_NEAR(0.0, state.getLinkState("link_a")->getGlobalLinkTransform().getRotation().z(), 1e-5);
    EXPECT_NEAR(1.0, state.getLinkState("link_a")->getGlobalLinkTransform().getRotation().w(), 1e-5);
    
    EXPECT_NEAR(1.0, state.getLinkState("link_b")->getGlobalLinkTransform().getOrigin().x(), 1e-5);
    EXPECT_NEAR(1.5, state.getLinkState("link_b")->getGlobalLinkTransform().getOrigin().y(), 1e-5);
    EXPECT_NEAR(0.0, state.getLinkState("link_b")->getGlobalLinkTransform().getOrigin().z(), 1e-5);
    EXPECT_NEAR(0.0, state.getLinkState("link_b")->getGlobalLinkTransform().getRotation().x(), 1e-5);
    EXPECT_NEAR(-0.20846, state.getLinkState("link_b")->getGlobalLinkTransform().getRotation().y(), 1e-5);
    EXPECT_NEAR(0.0, state.getLinkState("link_b")->getGlobalLinkTransform().getRotation().z(), 1e-5);
    EXPECT_NEAR(0.978031, state.getLinkState("link_b")->getGlobalLinkTransform().getRotation().w(), 1e-5);
    
    EXPECT_NEAR(1.1, state.getLinkState("link_c")->getGlobalLinkTransform().getOrigin().x(), 1e-5);
    EXPECT_NEAR(1.4, state.getLinkState("link_c")->getGlobalLinkTransform().getOrigin().y(), 1e-5);
    EXPECT_NEAR(0.0, state.getLinkState("link_c")->getGlobalLinkTransform().getOrigin().z(), 1e-5);
    EXPECT_NEAR(0.0, state.getLinkState("link_c")->getGlobalLinkTransform().getRotation().x(), 1e-5);
    EXPECT_NEAR(0.0, state.getLinkState("link_c")->getGlobalLinkTransform().getRotation().y(), 1e-5);
    EXPECT_NEAR(0.0, state.getLinkState("link_c")->getGlobalLinkTransform().getRotation().z(), 1e-5);
    EXPECT_NEAR(1.0, state.getLinkState("link_c")->getGlobalLinkTransform().getRotation().w(), 1e-5);

    //bonus bounds lookup test
    std::vector<std::string> jn;
    jn.push_back("planar_x");
    jn.push_back("planar_th");
    jn.push_back("base_joint");
    EXPECT_TRUE(state.areJointsWithinBounds(jn));
    
    jn.push_back("monkey");
    EXPECT_FALSE(state.areJointsWithinBounds(jn));
  }

  delete model;
}
예제 #3
0
TEST(LoadingAndFK, SimpleRobot)
{
    static const std::string MODEL1 =
        "<?xml version=\"1.0\" ?>"
        "<robot name=\"myrobot\">"
        "<link name=\"base_link\">"
        "  <inertial>"
        "    <mass value=\"2.81\"/>"
        "    <origin rpy=\"0 0 0\" xyz=\"0.0 0.099 .0\"/>"
        "    <inertia ixx=\"0.1\" ixy=\"-0.2\" ixz=\"0.5\" iyy=\"-.09\" iyz=\"1\" izz=\"0.101\"/>"
        "  </inertial>"
        "  <collision name=\"my_collision\">"
        "    <origin rpy=\"0 0 -1\" xyz=\"-0.1 0 0\"/>"
        "    <geometry>"
        "      <box size=\"1 2 1\" />"
        "    </geometry>"
        "  </collision>"
        "  <visual>"
        "    <origin rpy=\"0 0 0\" xyz=\"0.0 0 0\"/>"
        "    <geometry>"
        "      <box size=\"1 2 1\" />"
        "    </geometry>"
        "  </visual>"
        "</link>"
        "</robot>";

    static const std::string MODEL1_INFO =
        "Model myrobot in frame odom_combined, of dimension 3\n"
        "Joint values bounds:\n"
        "   base_joint/x [DBL_MIN, DBL_MAX]\n"
        "   base_joint/y [DBL_MIN, DBL_MAX]\n"
        "   base_joint/theta [-3.14159, 3.14159]\n"
        "Available groups: \n"
        "   base (of dimension 3):\n"
        "    joints:\n"
        "      base_joint\n"
        "    links:\n"
        "      base_link\n"
        "    roots:\n"
        "      base_joint";

    static const std::string SMODEL1 =
        "<?xml version=\"1.0\" ?>"
        "<robot name=\"myrobot\">"
        "<virtual_joint name=\"base_joint\" child_link=\"base_link\" parent_frame=\"odom_combined\" type=\"planar\"/>"
        "<group name=\"base\">"
        "<joint name=\"base_joint\"/>"
        "</group>"
        "</robot>";

    boost::shared_ptr<urdf::ModelInterface> urdfModel = urdf::parseURDF(MODEL1);

    boost::shared_ptr<srdf::Model> srdfModel(new srdf::Model());
    srdfModel->initString(*urdfModel, SMODEL1);

    planning_models::KinematicModelPtr model(new planning_models::KinematicModel(urdfModel, srdfModel));
    planning_models::KinematicState state(model);

    EXPECT_EQ((unsigned int)3, state.getVariableCount());

    state.setToDefaultValues();

    const std::vector<planning_models::KinematicState::JointState*>& joint_states = state.getJointStateVector();
    EXPECT_EQ((unsigned int)1, joint_states.size());
    EXPECT_EQ((unsigned int)3, joint_states[0]->getVariableValues().size());


    std::stringstream ssi;
    model->printModelInfo(ssi);
    EXPECT_TRUE(sameStringIgnoringWS(MODEL1_INFO, ssi.str())) << ssi.str();


    std::map<std::string, double> joint_values;
    joint_values["base_joint/x"] = 10.0;
    joint_values["base_joint/y"] = 8.0;

    //testing incomplete state
    std::vector<std::string> missing_states;
    state.setStateValues(joint_values, missing_states);
    ASSERT_EQ(missing_states.size(), 1);
    EXPECT_EQ(missing_states[0], std::string("base_joint/theta"));
    joint_values["base_joint/theta"] = 0.0;

    state.setStateValues(joint_values, missing_states);
    ASSERT_EQ(missing_states.size(), 0);

    EXPECT_NEAR(10.0, state.getLinkState("base_link")->getGlobalLinkTransform().translation().x(), 1e-5);
    EXPECT_NEAR(8.0, state.getLinkState("base_link")->getGlobalLinkTransform().translation().y(), 1e-5);
    EXPECT_NEAR(0.0, state.getLinkState("base_link")->getGlobalLinkTransform().translation().z(), 1e-5);

    //making sure that values get copied
    planning_models::KinematicState new_state(state);
    EXPECT_NEAR(10.0, new_state.getLinkState("base_link")->getGlobalLinkTransform().translation().x(), 1e-5);
    EXPECT_NEAR(8.0, new_state.getLinkState("base_link")->getGlobalLinkTransform().translation().y(), 1e-5);
    EXPECT_NEAR(0.0, new_state.getLinkState("base_link")->getGlobalLinkTransform().translation().z(), 1e-5);

    const std::map<std::string, unsigned int>& ind_map = model->getJointVariablesIndexMap();
    std::vector<double> jv(state.getVariableCount(), 0.0);
    jv[ind_map.at("base_joint/x")] = 10.0;
    jv[ind_map.at("base_joint/y")] = 8.0;
    jv[ind_map.at("base_joint/theta")] = 0.0;

    state.setStateValues(jv);
    EXPECT_NEAR(10.0, state.getLinkState("base_link")->getGlobalLinkTransform().translation().x(), 1e-5);
    EXPECT_NEAR(8.0, state.getLinkState("base_link")->getGlobalLinkTransform().translation().y(), 1e-5);
    EXPECT_NEAR(0.0, state.getLinkState("base_link")->getGlobalLinkTransform().translation().z(), 1e-5);
}
TEST(LoadingAndFK, SimpleRobot)
{   
  static const std::string MODEL1 = 
    "<?xml version=\"1.0\" ?>" 
    "<robot name=\"myrobot\">" 
    "<link name=\"base_link\">"
    "  <inertial>"
    "    <mass value=\"2.81\"/>"
    "    <origin rpy=\"0 0 0\" xyz=\"0.0 0.099 .0\"/>"
    "    <inertia ixx=\"0.1\" ixy=\"-0.2\" ixz=\"0.5\" iyy=\"-.09\" iyz=\"1\" izz=\"0.101\"/>"
    "  </inertial>"
    "  <collision name=\"my_collision\">"
    "    <origin rpy=\"0 0 -1\" xyz=\"-0.1 0 0\"/>"
    "    <geometry>"
    "      <box size=\"1 2 1\" />"
    "    </geometry>"
    "  </collision>"
    "  <visual>"
    "    <origin rpy=\"0 0 0\" xyz=\"0.0 0 0\"/>"
    "    <geometry>"
    "      <box size=\"1 2 1\" />"
    "    </geometry>"
    "  </visual>"
    "</link>"
    "</robot>";
    
  static const std::string MODEL1_INFO = 
    "Complete model state dimension = 3\n"
    "State bounds: [-3.14159, 3.14159] [-DBL_MAX, DBL_MAX] [-DBL_MAX, DBL_MAX]\n"
    "Root joint : base_joint \n"
    "Available groups: base \n"
    "Group base has 1 roots: base_joint \n";

  std::vector<planning_models::KinematicModel::MultiDofConfig> multi_dof_configs;
  planning_models::KinematicModel::MultiDofConfig config("base_joint");
  config.type = "Planar";
  config.parent_frame_id = "odom_combined";
  config.child_frame_id = "base_link";
  multi_dof_configs.push_back(config);
    
  urdf::Model urdfModel;
  urdfModel.initString(MODEL1);

  std::vector<std::string> gc_joints;
  gc_joints.push_back("base_joint");
  std::vector<std::string> empty;
  std::vector<planning_models::KinematicModel::GroupConfig> gcs;
  gcs.push_back(planning_models::KinematicModel::GroupConfig("base", gc_joints, empty));

  planning_models::KinematicModel* model(new planning_models::KinematicModel(urdfModel,gcs,multi_dof_configs));

  //bracketing so the state gets destroyed before we bring down the model
  {    
    planning_models::KinematicState state(model);
    
    EXPECT_EQ((unsigned int)3, state.getDimension());
    
    state.setKinematicStateToDefault();

    const std::vector<planning_models::KinematicState::JointState*>& joint_states = state.getJointStateVector();
    EXPECT_EQ((unsigned int)1, joint_states.size());
    EXPECT_EQ((unsigned int)3, joint_states[0]->getJointStateValues().size());
    
    std::stringstream ssi;
    state.printStateInfo(ssi);
    EXPECT_TRUE(sameStringIgnoringWS(MODEL1_INFO, ssi.str())) << ssi.str();
    
    
    std::map<std::string, double> joint_values;
    joint_values["planar_x"]=10.0;
    joint_values["planar_y"]=8.0;
    
    //testing incomplete state
    std::vector<std::string> missing_states;
    EXPECT_FALSE(state.setKinematicState(joint_values,
                                         missing_states));
    ASSERT_EQ(missing_states.size(),1);
    EXPECT_EQ(missing_states[0],std::string("planar_th"));
    joint_values["planar_th"]=0.0;

    EXPECT_TRUE(state.setKinematicState(joint_values,
                                         missing_states));
    ASSERT_EQ(missing_states.size(),0);

    EXPECT_NEAR(10.0, state.getLinkState("base_link")->getGlobalLinkTransform().getOrigin().x(), 1e-5);
    EXPECT_NEAR(8.0, state.getLinkState("base_link")->getGlobalLinkTransform().getOrigin().y(), 1e-5);
    EXPECT_NEAR(0.0, state.getLinkState("base_link")->getGlobalLinkTransform().getOrigin().z(), 1e-5);

    //making sure that values get copied
    planning_models::KinematicState new_state(state);
    EXPECT_NEAR(10.0, new_state.getLinkState("base_link")->getGlobalLinkTransform().getOrigin().x(), 1e-5);
    EXPECT_NEAR(8.0, new_state.getLinkState("base_link")->getGlobalLinkTransform().getOrigin().y(), 1e-5);
    EXPECT_NEAR(0.0, new_state.getLinkState("base_link")->getGlobalLinkTransform().getOrigin().z(), 1e-5);
    
    const std::map<std::string, unsigned int>& ind_map = state.getKinematicStateIndexMap();
    std::vector<double> jv(state.getDimension(), 0.0);
    jv[ind_map.at("planar_x")] = 10.0;
    jv[ind_map.at("planar_y")] = 8.0;
    jv[ind_map.at("planar_th")] = 0.0;
    
    state.setKinematicState(jv);
    EXPECT_NEAR(10.0, state.getLinkState("base_link")->getGlobalLinkTransform().getOrigin().x(), 1e-5);
    EXPECT_NEAR(8.0, state.getLinkState("base_link")->getGlobalLinkTransform().getOrigin().y(), 1e-5);
    EXPECT_NEAR(0.0, state.getLinkState("base_link")->getGlobalLinkTransform().getOrigin().z(), 1e-5);
  } 
  delete model;
}