play_motion_test.cpp
Go to the documentation of this file.
00001 
00002 // Copyright (C) 2013, PAL Robotics S.L.
00003 //
00004 // Redistribution and use in source and binary forms, with or without
00005 // modification, are permitted provided that the following conditions are met:
00006 //   * Redistributions of source code must retain the above copyright notice,
00007 //     this list of conditions and the following disclaimer.
00008 //   * Redistributions in binary form must reproduce the above copyright
00009 //     notice, this list of conditions and the following disclaimer in the
00010 //     documentation and/or other materials provided with the distribution.
00011 //   * Neither the name of PAL Robotics S.L. nor the names of its
00012 //     contributors may be used to endorse or promote products derived from
00013 //     this software without specific prior written permission.
00014 //
00015 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00016 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00017 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00018 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00019 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00020 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00021 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00022 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00023 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00024 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00025 // POSSIBILITY OF SUCH DAMAGE.
00027 
00029 
00030 #include <gtest/gtest.h>
00031 
00032 #include <boost/thread.hpp>
00033 #include <ros/ros.h>
00034 #include <ros/time.h>
00035 #include <actionlib/client/simple_action_client.h>
00036 #include <sensor_msgs/JointState.h>
00037 
00038 #include "play_motion_msgs/PlayMotionAction.h"
00039 
00040 typedef actionlib::SimpleClientGoalState GS;
00041 typedef play_motion_msgs::PlayMotionResult PMR;
00042 
00043 class PlayMotionTestClient
00044 {
00045   typedef actionlib::SimpleActionClient<play_motion_msgs::PlayMotionAction> ActionClient;
00046   typedef boost::shared_ptr<ActionClient> ActionClientPtr;
00047   typedef play_motion_msgs::PlayMotionGoal ActionGoal;
00048   typedef actionlib::SimpleClientGoalState ActionGoalState;
00049   typedef boost::shared_ptr<ActionGoalState> ActionGoalStatePtr;
00050 
00051 public:
00052   PlayMotionTestClient()
00053   {
00054     ac_.reset(new ActionClient("/play_motion"));
00055     js_sub_ = nh_.subscribe("/joint_states", 10, &PlayMotionTestClient::jsCb, this);
00056   }
00057 
00058   int playMotion(const std::string& motion_name, bool skip_planning)
00059   {
00060     ActionGoal goal;
00061     goal.motion_name = motion_name;
00062     goal.skip_planning = skip_planning;
00063 
00064     ac_->waitForServer();
00065     gs_.reset(new ActionGoalState(ac_->sendGoalAndWait(goal)));
00066     ret_ = ac_->getResult()->error_code;
00067     return ret_;
00068   }
00069 
00070   double getJointPos(const std::string& joint_name)
00071   {
00072     unsigned int i;
00073     for (i = 0; i < js_.name.size(); ++i)
00074     {
00075       if (js_.name[i] == joint_name)
00076         return js_.position[i];
00077     }
00078 
00079     return std::numeric_limits<double>::quiet_NaN();
00080   }
00081 
00082   void shouldFinishWith(int code, int gstate)
00083   {
00084     EXPECT_EQ(code, ret_);
00085     EXPECT_EQ(gstate, gs_->state_);
00086   }
00087 
00088   void shouldFailWithCode(int code)
00089   {
00090     shouldFinishWith(code, GS::REJECTED);
00091   }
00092 
00093   void shouldSucceed()
00094   {
00095     shouldFinishWith(PMR::SUCCEEDED, GS::SUCCEEDED);
00096   }
00097 
00098 
00099 protected:
00100   void jsCb(const sensor_msgs::JointStatePtr& js) { js_ = *js; }
00101 
00102 private:
00103   int ret_;
00104   ActionGoalStatePtr gs_;
00105   ros::NodeHandle nh_;
00106   ActionClientPtr ac_;
00107   sensor_msgs::JointState js_;
00108   ros::Subscriber js_sub_;
00109 };
00110 
00111 TEST(PlayMotionTest, basicReachPose)
00112 {
00113   PlayMotionTestClient pmtc;
00114 
00115   pmtc.playMotion("pose1", true);
00116   pmtc.shouldSucceed();
00117 
00118   double final_pos = pmtc.getJointPos("joint1");
00119   EXPECT_NEAR(final_pos, 1.8, 0.01);
00120 }
00121 
00122 TEST(PlayMotionTest, rejectSecondGoal)
00123 {
00124   PlayMotionTestClient pmtc1;
00125   PlayMotionTestClient pmtc2;
00126 
00127   boost::thread t(boost::bind(&PlayMotionTestClient::playMotion, &pmtc1, "home", true));
00128   ros::Duration(0.3).sleep();
00129 
00130   pmtc2.playMotion("home", true);
00131   pmtc2.shouldFailWithCode(PMR::CONTROLLER_BUSY);
00132 
00133   t.join();
00134   pmtc1.shouldSucceed();
00135 }
00136 
00137 TEST(PlayMotionTest, badMotionName)
00138 {
00139   PlayMotionTestClient pmtc;
00140   pmtc.playMotion("inexistant_motion", true);
00141   pmtc.shouldFailWithCode(PMR::MOTION_NOT_FOUND);
00142 
00143   pmtc.playMotion("", true);
00144   pmtc.shouldFailWithCode(PMR::MOTION_NOT_FOUND);
00145 }
00146 
00147 int main(int argc, char** argv)
00148 {
00149   testing::InitGoogleTest(&argc, argv);
00150   ros::init(argc, argv, "play_motion_test");
00151 
00152   ros::AsyncSpinner spinner(1);
00153   spinner.start();
00154   ros::Duration(2.0).sleep(); // wait a bit for the controllers to start
00155   int ret = RUN_ALL_TESTS();
00156   spinner.stop();
00157   ros::shutdown();
00158   return ret;
00159 }
00160 


play_motion
Author(s): Paul Mathieu
autogenerated on Wed Aug 26 2015 15:29:25