00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <gtest/gtest.h>
00039 #include <moveit/robot_interaction/locked_robot_state.h>
00040 #include <moveit/robot_model/robot_model.h>
00041 #include <moveit/robot_state/robot_state.h>
00042 #include <urdf_parser/urdf_parser.h>
00043
00044
00045
00046 static const char *URDF_STR =
00047 "<?xml version=\"1.0\" ?>"
00048 "<robot name=\"one_robot\">"
00049 "<link name=\"base_link\">"
00050 " <inertial>"
00051 " <mass value=\"2.81\"/>"
00052 " <origin rpy=\"0 0 0\" xyz=\"0.0 0.0 .0\"/>"
00053 " <inertia ixx=\"0.1\" ixy=\"-0.2\" ixz=\"0.5\" iyy=\"-.09\" iyz=\"1\" izz=\"0.101\"/>"
00054 " </inertial>"
00055 " <collision name=\"my_collision\">"
00056 " <origin rpy=\"0 0 0\" xyz=\"0 0 0\"/>"
00057 " <geometry>"
00058 " <box size=\"1 2 1\" />"
00059 " </geometry>"
00060 " </collision>"
00061 " <visual>"
00062 " <origin rpy=\"0 0 0\" xyz=\"0.0 0 0\"/>"
00063 " <geometry>"
00064 " <box size=\"1 2 1\" />"
00065 " </geometry>"
00066 " </visual>"
00067 "</link>"
00068 "<joint name=\"joint_a\" type=\"continuous\">"
00069 " <axis xyz=\"0 0 1\"/>"
00070 " <parent link=\"base_link\"/>"
00071 " <child link=\"link_a\"/>"
00072 " <origin rpy=\" 0.0 0 0 \" xyz=\"0.0 0 0 \"/>"
00073 "</joint>"
00074 "<link name=\"link_a\">"
00075 " <inertial>"
00076 " <mass value=\"1.0\"/>"
00077 " <origin rpy=\"0 0 0\" xyz=\"0.0 0.0 .0\"/>"
00078 " <inertia ixx=\"0.1\" ixy=\"-0.2\" ixz=\"0.5\" iyy=\"-.09\" iyz=\"1\" izz=\"0.101\"/>"
00079 " </inertial>"
00080 " <collision>"
00081 " <origin rpy=\"0 0 0\" xyz=\"0 0 0\"/>"
00082 " <geometry>"
00083 " <box size=\"1 2 1\" />"
00084 " </geometry>"
00085 " </collision>"
00086 " <visual>"
00087 " <origin rpy=\"0 0 0\" xyz=\"0.0 0 0\"/>"
00088 " <geometry>"
00089 " <box size=\"1 2 1\" />"
00090 " </geometry>"
00091 " </visual>"
00092 "</link>"
00093 "<joint name=\"joint_b\" type=\"fixed\">"
00094 " <parent link=\"link_a\"/>"
00095 " <child link=\"link_b\"/>"
00096 " <origin rpy=\" 0.0 -0.42 0 \" xyz=\"0.0 0.5 0 \"/>"
00097 "</joint>"
00098 "<link name=\"link_b\">"
00099 " <inertial>"
00100 " <mass value=\"1.0\"/>"
00101 " <origin rpy=\"0 0 0\" xyz=\"0.0 0.0 .0\"/>"
00102 " <inertia ixx=\"0.1\" ixy=\"-0.2\" ixz=\"0.5\" iyy=\"-.09\" iyz=\"1\" izz=\"0.101\"/>"
00103 " </inertial>"
00104 " <collision>"
00105 " <origin rpy=\"0 0 0\" xyz=\"0 0 0\"/>"
00106 " <geometry>"
00107 " <box size=\"1 2 1\" />"
00108 " </geometry>"
00109 " </collision>"
00110 " <visual>"
00111 " <origin rpy=\"0 0 0\" xyz=\"0.0 0 0\"/>"
00112 " <geometry>"
00113 " <box size=\"1 2 1\" />"
00114 " </geometry>"
00115 " </visual>"
00116 "</link>"
00117 " <joint name=\"joint_c\" type=\"prismatic\">"
00118 " <axis xyz=\"1 0 0\"/>"
00119 " <limit effort=\"100.0\" lower=\"0.0\" upper=\"0.09\" velocity=\"0.2\"/>"
00120 " <safety_controller k_position=\"20.0\" k_velocity=\"500.0\" soft_lower_limit=\"0.0\" soft_upper_limit=\"0.089\"/>"
00121 " <parent link=\"link_b\"/>"
00122 " <child link=\"link_c\"/>"
00123 " <origin rpy=\" 0.0 0.42 0.0 \" xyz=\"0.0 -0.1 0 \"/>"
00124 " </joint>"
00125 "<link name=\"link_c\">"
00126 " <inertial>"
00127 " <mass value=\"1.0\"/>"
00128 " <origin rpy=\"0 0 0\" xyz=\"0.0 0 .0\"/>"
00129 " <inertia ixx=\"0.1\" ixy=\"-0.2\" ixz=\"0.5\" iyy=\"-.09\" iyz=\"1\" izz=\"0.101\"/>"
00130 " </inertial>"
00131 " <collision>"
00132 " <origin rpy=\"0 0 0\" xyz=\"0 0 0\"/>"
00133 " <geometry>"
00134 " <box size=\"1 2 1\" />"
00135 " </geometry>"
00136 " </collision>"
00137 " <visual>"
00138 " <origin rpy=\"0 0 0\" xyz=\"0.0 0 0\"/>"
00139 " <geometry>"
00140 " <box size=\"1 2 1\" />"
00141 " </geometry>"
00142 " </visual>"
00143 "</link>"
00144 " <joint name=\"mim_f\" type=\"prismatic\">"
00145 " <axis xyz=\"1 0 0\"/>"
00146 " <limit effort=\"100.0\" lower=\"0.0\" upper=\"0.19\" velocity=\"0.2\"/>"
00147 " <parent link=\"link_c\"/>"
00148 " <child link=\"link_d\"/>"
00149 " <origin rpy=\" 0.0 0.1 0.0 \" xyz=\"0.1 0.1 0 \"/>"
00150 " <mimic joint=\"joint_f\" multiplier=\"1.5\" offset=\"0.1\"/>"
00151 " </joint>"
00152 " <joint name=\"joint_f\" type=\"prismatic\">"
00153 " <axis xyz=\"1 0 0\"/>"
00154 " <limit effort=\"100.0\" lower=\"0.0\" upper=\"0.19\" velocity=\"0.2\"/>"
00155 " <parent link=\"link_d\"/>"
00156 " <child link=\"link_e\"/>"
00157 " <origin rpy=\" 0.0 0.1 0.0 \" xyz=\"0.1 0.1 0 \"/>"
00158 " </joint>"
00159 "<link name=\"link_d\">"
00160 " <collision>"
00161 " <origin rpy=\"0 0 0\" xyz=\"0 0 0\"/>"
00162 " <geometry>"
00163 " <box size=\"1 2 1\" />"
00164 " </geometry>"
00165 " </collision>"
00166 " <visual>"
00167 " <origin rpy=\"0 1 0\" xyz=\"0 0.1 0\"/>"
00168 " <geometry>"
00169 " <box size=\"1 2 1\" />"
00170 " </geometry>"
00171 " </visual>"
00172 "</link>"
00173 "<link name=\"link_e\">"
00174 " <collision>"
00175 " <origin rpy=\"0 0 0\" xyz=\"0 0 0\"/>"
00176 " <geometry>"
00177 " <box size=\"1 2 1\" />"
00178 " </geometry>"
00179 " </collision>"
00180 " <visual>"
00181 " <origin rpy=\"0 1 0\" xyz=\"0 0.1 0\"/>"
00182 " <geometry>"
00183 " <box size=\"1 2 1\" />"
00184 " </geometry>"
00185 " </visual>"
00186 "</link>"
00187 "</robot>";
00188
00189 static const char *SRDF_STR =
00190 "<?xml version=\"1.0\" ?>"
00191 "<robot name=\"one_robot\">"
00192 "<virtual_joint name=\"base_joint\" child_link=\"base_link\" parent_frame=\"odom_combined\" type=\"planar\"/>"
00193 "<group name=\"base_from_joints\">"
00194 "<joint name=\"base_joint\"/>"
00195 "<joint name=\"joint_a\"/>"
00196 "<joint name=\"joint_c\"/>"
00197 "</group>"
00198 "<group name=\"mim_joints\">"
00199 "<joint name=\"joint_f\"/>"
00200 "<joint name=\"mim_f\"/>"
00201 "</group>"
00202 "<group name=\"base_with_subgroups\">"
00203 "<group name=\"base_from_base_to_tip\"/>"
00204 "<joint name=\"joint_c\"/>"
00205 "</group>"
00206 "<group name=\"base_from_base_to_tip\">"
00207 "<chain base_link=\"base_link\" tip_link=\"link_b\"/>"
00208 "<joint name=\"base_joint\"/>"
00209 "</group>"
00210 "</robot>";
00211
00212
00213 enum {
00214 JOINT_A = 3,
00215 JOINT_C = 4,
00216 MIM_F = 5,
00217 JOINT_F = 6
00218 };
00219
00220 static moveit::core::RobotModelPtr getModel()
00221 {
00222 static moveit::core::RobotModelPtr model;
00223 if (!model)
00224 {
00225 boost::shared_ptr<urdf::ModelInterface> urdf(urdf::parseURDF(URDF_STR));
00226 boost::shared_ptr<srdf::Model> srdf(new srdf::Model());
00227 srdf->initString(*urdf, SRDF_STR);
00228 model.reset(new moveit::core::RobotModel(urdf, srdf));
00229 }
00230 return model;
00231 }
00232
00233
00234 TEST(LockedRobotState, load)
00235 {
00236 moveit::core::RobotModelPtr model = getModel();
00237
00238 robot_interaction::LockedRobotState ls1(model);
00239
00240 moveit::core::RobotState state2(model);
00241 state2.setToDefaultValues();
00242 robot_interaction::LockedRobotState ls2(state2);
00243
00244 robot_interaction::LockedRobotStatePtr ls4(
00245 new robot_interaction::LockedRobotState(model));
00246 }
00247
00248
00249 TEST(LockedRobotState, URDF_sanity)
00250 {
00251 moveit::core::RobotModelPtr model = getModel();
00252 robot_interaction::LockedRobotState ls1(model);
00253
00254 EXPECT_EQ(ls1.getState()->getVariableNames()[JOINT_A], "joint_a");
00255 }
00256
00257
00258 class Super1 : public robot_interaction::LockedRobotState
00259 {
00260 public:
00261 Super1(const robot_model::RobotModelPtr& model)
00262 : LockedRobotState(model)
00263 , cnt_(0)
00264 {}
00265
00266 virtual void robotStateChanged()
00267 {
00268 cnt_++;
00269 }
00270
00271 int cnt_;
00272 };
00273
00274 static void modify1(robot_state::RobotState* state)
00275 {
00276 state->setVariablePosition(JOINT_A, 0.00006);
00277 }
00278
00279 TEST(LockedRobotState, robotStateChanged)
00280 {
00281 moveit::core::RobotModelPtr model = getModel();
00282
00283 Super1 ls1(model);
00284
00285 EXPECT_EQ(ls1.cnt_, 0);
00286
00287 robot_state::RobotState cp1(*ls1.getState());
00288 cp1.setVariablePosition(JOINT_A, 0.00001);
00289 cp1.setVariablePosition(JOINT_C, 0.00002);
00290 cp1.setVariablePosition(JOINT_F, 0.00003);
00291 ls1.setState(cp1);
00292
00293 EXPECT_EQ(ls1.cnt_, 1);
00294
00295 ls1.modifyState(modify1);
00296 EXPECT_EQ(ls1.cnt_, 2);
00297
00298 ls1.modifyState(modify1);
00299 EXPECT_EQ(ls1.cnt_, 3);
00300 }
00301
00302
00303
00304 class MyInfo
00305 {
00306 public:
00307 MyInfo()
00308 : quit_(false)
00309 {}
00310
00311
00312 void setThreadFunc(robot_interaction::LockedRobotState* locked_state,
00313 int* counter,
00314 double offset);
00315
00316
00317 void modifyThreadFunc(robot_interaction::LockedRobotState* locked_state,
00318 int* counter,
00319 double offset);
00320
00321
00322 void checkThreadFunc(robot_interaction::LockedRobotState* locked_state,
00323 int* counter);
00324
00325
00326 void waitThreadFunc(robot_interaction::LockedRobotState* locked_state,
00327 int** counters,
00328 int max);
00329
00330 private:
00331
00332 void modifyFunc( robot_state::RobotState* state, double val);
00333
00334
00335 void checkState(robot_interaction::LockedRobotState &locked_state);
00336
00337
00338 boost::mutex cnt_lock_;
00339
00340
00341
00342 bool quit_;
00343 };
00344
00345
00346 void MyInfo::checkState(robot_interaction::LockedRobotState &locked_state)
00347 {
00348 robot_state::RobotStateConstPtr s = locked_state.getState();
00349
00350 robot_state::RobotState cp1(*s);
00351
00352
00353 cnt_lock_.lock();
00354 cnt_lock_.unlock();
00355 cnt_lock_.lock();
00356 cnt_lock_.unlock();
00357 cnt_lock_.lock();
00358 cnt_lock_.unlock();
00359
00360
00361 EXPECT_EQ(s->getVariablePositions()[MIM_F],
00362 s->getVariablePositions()[JOINT_F] * 1.5 + 0.1);
00363
00364 robot_state::RobotState cp2(*s);
00365
00366 EXPECT_NE(cp1.getVariablePositions(), cp2.getVariablePositions());
00367 EXPECT_NE(cp1.getVariablePositions(), s->getVariablePositions());
00368
00369 int cnt = cp1.getVariableCount();
00370 for (int i = 0 ; i < cnt ; ++i)
00371 {
00372 EXPECT_EQ(cp1.getVariablePositions()[i],
00373 cp2.getVariablePositions()[i]);
00374 EXPECT_EQ(cp1.getVariablePositions()[i],
00375 s->getVariablePositions()[i]);
00376 }
00377
00378
00379 EXPECT_EQ(s->getVariablePositions()[MIM_F],
00380 s->getVariablePositions()[JOINT_F] * 1.5 + 0.1);
00381 }
00382
00383
00384 void MyInfo::checkThreadFunc(
00385 robot_interaction::LockedRobotState* locked_state,
00386 int* counter)
00387 {
00388 bool go = true;
00389 while(go)
00390 {
00391 for (int loops = 0 ; loops < 100 ; ++loops)
00392 {
00393 checkState(*locked_state);
00394 }
00395
00396 cnt_lock_.lock();
00397 go = !quit_;
00398 ++*counter;
00399 cnt_lock_.unlock();
00400 }
00401 }
00402
00403
00404 void MyInfo::setThreadFunc(
00405 robot_interaction::LockedRobotState* locked_state,
00406 int* counter,
00407 double offset)
00408 {
00409 bool go = true;
00410 while(go)
00411 {
00412 double val = offset;
00413 for (int loops = 0 ; loops < 100 ; ++loops)
00414 {
00415 val += 0.0001;
00416 robot_state::RobotState cp1(*locked_state->getState());
00417
00418 cp1.setVariablePosition(JOINT_A, val + 0.00001);
00419 cp1.setVariablePosition(JOINT_C, val + 0.00002);
00420 cp1.setVariablePosition(JOINT_F, val + 0.00003);
00421
00422 locked_state->setState(cp1);
00423 }
00424
00425 cnt_lock_.lock();
00426 go = !quit_;
00427 ++*counter;
00428 cnt_lock_.unlock();
00429
00430 checkState(*locked_state);
00431
00432 val += 0.000001;
00433 }
00434 }
00435
00436
00437 void MyInfo::modifyFunc(
00438 robot_state::RobotState* state,
00439 double val)
00440 {
00441 state->setVariablePosition(JOINT_A, val + 0.00001);
00442 state->setVariablePosition(JOINT_C, val + 0.00002);
00443 state->setVariablePosition(JOINT_F, val + 0.00003);
00444 }
00445
00446
00447 void MyInfo::modifyThreadFunc(
00448 robot_interaction::LockedRobotState* locked_state,
00449 int* counter,
00450 double offset)
00451 {
00452 bool go = true;
00453 while(go)
00454 {
00455 double val = offset;
00456 for (int loops = 0 ; loops < 100 ; ++loops)
00457 {
00458 val += 0.0001;
00459
00460 locked_state->modifyState(boost::bind(&MyInfo::modifyFunc,
00461 this,
00462 _1,
00463 val));
00464 }
00465
00466 cnt_lock_.lock();
00467 go = !quit_;
00468 ++*counter;
00469 cnt_lock_.unlock();
00470
00471 checkState(*locked_state);
00472
00473 val += 0.000001;
00474 }
00475 }
00476
00477
00478 void MyInfo::waitThreadFunc(
00479 robot_interaction::LockedRobotState* locked_state,
00480 int** counters,
00481 int max)
00482 {
00483 bool go = true;
00484 while(go)
00485 {
00486 go = false;
00487 cnt_lock_.lock();
00488 for (int i = 0 ; counters[i] ; ++i)
00489 {
00490 if (counters[i][0] < max)
00491 go = true;
00492 }
00493 cnt_lock_.unlock();
00494
00495 checkState(*locked_state);
00496 checkState(*locked_state);
00497 }
00498 cnt_lock_.lock();
00499 quit_ = true;
00500 cnt_lock_.unlock();
00501 }
00502
00503
00504
00505
00506
00507 static void runThreads(int ncheck, int nset, int nmod)
00508 {
00509 MyInfo info;
00510
00511 moveit::core::RobotModelPtr model = getModel();
00512 robot_interaction::LockedRobotState ls1(model);
00513
00514 int num = ncheck + nset + nmod;
00515
00516 typedef int *int_ptr;
00517 typedef boost::thread * thread_ptr;
00518 int *cnt = new int[num];
00519 int_ptr *counters = new int_ptr[num+1];
00520 thread_ptr *threads = new thread_ptr[num];
00521
00522 int p = 0;
00523 double val = 0.1;
00524
00525
00526 for (int i = 0 ; i < ncheck ; ++i)
00527 {
00528 cnt[p] = 0;
00529 counters[p] = &cnt[p];
00530 threads[p] = new boost::thread(&MyInfo::checkThreadFunc,
00531 &info,
00532 &ls1,
00533 &cnt[p]);
00534 val += 0.1;
00535 p++;
00536 }
00537
00538
00539 for (int i = 0 ; i < nset ; ++i)
00540 {
00541 cnt[p] = 0;
00542 counters[p] = &cnt[p];
00543 threads[p] = new boost::thread(&MyInfo::setThreadFunc,
00544 &info,
00545 &ls1,
00546 &cnt[p],
00547 val);
00548 val += 0.1;
00549 p++;
00550 }
00551
00552
00553 for (int i = 0 ; i < nmod ; ++i)
00554 {
00555 cnt[p] = 0;
00556 counters[p] = &cnt[p];
00557 threads[p] = new boost::thread(&MyInfo::modifyThreadFunc,
00558 &info,
00559 &ls1,
00560 &cnt[p],
00561 val);
00562 val += 0.1;
00563 p++;
00564 }
00565
00566 ASSERT_EQ(p, num);
00567 counters[p] = NULL;
00568
00569
00570
00571 boost::thread wthread(&MyInfo::waitThreadFunc,
00572 &info,
00573 &ls1,
00574 counters,
00575 1000);
00576
00577
00578 for (int i = 0 ; i < p ; ++i)
00579 {
00580 threads[i]->join();
00581 wthread.join();
00582 }
00583
00584
00585 for (int i = 0 ; i < p ; ++i)
00586 {
00587 delete threads[i];
00588 }
00589 delete[] cnt;
00590 delete[] counters;
00591 delete[] threads;
00592 }
00593
00594 TEST(LockedRobotState, set1)
00595 {
00596 runThreads(1, 1, 0);
00597 }
00598
00599 TEST(LockedRobotState, set2)
00600 {
00601 runThreads(1, 2, 0);
00602 }
00603
00604 TEST(LockedRobotState, set3)
00605 {
00606 runThreads(1, 3, 0);
00607 }
00608
00609 TEST(LockedRobotState, mod1)
00610 {
00611 runThreads(1, 0, 1);
00612 }
00613
00614 TEST(LockedRobotState, mod2)
00615 {
00616 runThreads(1, 0, 1);
00617 }
00618
00619 TEST(LockedRobotState, mod3)
00620 {
00621 runThreads(1, 0, 1);
00622 }
00623
00624 TEST(LockedRobotState, set1mod1)
00625 {
00626 runThreads(1, 1, 1);
00627 }
00628
00629 TEST(LockedRobotState, set2mod1)
00630 {
00631 runThreads(1, 2, 1);
00632 }
00633
00634 TEST(LockedRobotState, set1mod2)
00635 {
00636 runThreads(1, 1, 2);
00637 }
00638
00639 TEST(LockedRobotState, set3mod1)
00640 {
00641 runThreads(1, 3, 1);
00642 }
00643
00644 TEST(LockedRobotState, set1mod3)
00645 {
00646 runThreads(1, 1, 3);
00647 }
00648
00649 TEST(LockedRobotState, set3mod3)
00650 {
00651 runThreads(1, 3, 3);
00652 }
00653
00654 TEST(LockedRobotState, set3mod3c3)
00655 {
00656 runThreads(3, 3, 3);
00657 }
00658
00659 int main(int argc, char **argv)
00660 {
00661 testing::InitGoogleTest(&argc, argv);
00662 int arg;
00663
00664 return RUN_ALL_TESTS();
00665 }
00666
00667
00668