00001 #include <ros/ros.h>
00002 #include <tf/tf.h>
00003 #include <tf/transform_listener.h>
00004 #include <tf/tfMessage.h>
00005 #include <tf/transform_broadcaster.h>
00006
00007 #include <geometry_msgs/PoseStamped.h>
00008 #include <geometry_msgs/QuaternionStamped.h>
00009 #include <visualization_msgs/Marker.h>
00010 #include <visualization_msgs/MarkerArray.h>
00011
00012 #include <pr2_controllers_msgs/Pr2GripperCommandAction.h>
00013 #include <actionlib/client/simple_action_client.h>
00014
00015 #include <motld/TrackedObjects.h>
00016
00017 #include <mpc/types.h>
00018 #include <mpc/mpc.h>
00019 #include <mpc/finite_differences.h>
00020 #include <reactive_grasping_pr2/pr2_arm_ik.h>
00021
00022 #ifndef SQR
00023 #define SQR(X) ((X)*(X))
00024 #endif
00025
00026 using namespace MPC;
00027
00028 typedef actionlib::SimpleActionClient<pr2_controllers_msgs::Pr2GripperCommandAction> GripperClient;
00029
00030 class ArmMPC {
00031
00032 private:
00033 bool initialized_;
00034 VectorT center_;
00035 tf::TransformBroadcaster *tf_broadcaster_;
00036 tf::TransformListener *tf_transformer_;
00037
00038 ros::Subscriber obj_sub_;
00039
00040 ros::Publisher gripper_pose_pub_;
00041 ros::Publisher marker_pub_;
00042 int curr_t_;
00043
00044 float eps_;
00045 float max_mov_dist_;
00046
00047 bool on_way_to_goal_;
00048 bool last_goal_set_;
00049 bool last_pos_set_;
00050 VectorT last_goal_;
00051 VectorT last_pos_;
00052 pr2_arm_ik::Obstacles *obs_;
00053
00054 int n, m, N;
00055 bool restart_ddp_;
00056 DDPParams params;
00057 Trajectory curr_traj_;
00058 MatrixT u0_;
00059 geometry_msgs::PoseStamped gripper_pose_;
00060 GripperClient *close_gripper_;
00061
00062 ros::NodeHandle nh_;
00063 ros::NodeHandle private_nh_;
00064
00065
00066 std::string root_frame_;
00067 std::string gripper_frame_;
00068 std::string object_topic_;
00069 std::string gripper_action_topic_;
00070 std::string gripper_close_topic_;
00071 std::string marker_topic_;
00072
00073 public:
00074 ArmMPC(ros::NodeHandle &nh) : nh_(nh), private_nh_(ros::NodeHandle("~")), initialized_(false) {
00075
00076 private_nh_.param("root_frame", root_frame_, std::string("/torso_lift_link"));
00077 private_nh_.param("gripper_frame", gripper_frame_, std::string("/r_gripper_tool_frame"));
00078 private_nh_.param("object_topic", object_topic_, std::string("/objects"));
00079 private_nh_.param("gripper_action_topic", gripper_action_topic_, std::string("/r_cart/command_pose"));
00080 private_nh_.param("gripper_close_topic", gripper_close_topic_, std::string("/r_gripper_controller/gripper_action"));
00081 private_nh_.param("marker_topic", marker_topic_, std::string("MPC_markers"));
00082
00083
00084 tf_broadcaster_ = new tf::TransformBroadcaster();
00085 tf_transformer_ = new tf::TransformListener();
00086
00087
00088 obj_sub_ = nh_.subscribe(object_topic_, 1, &ArmMPC::mpc_callback, this);
00089
00090
00091 gripper_pose_pub_ = nh_.advertise<geometry_msgs::PoseStamped>(gripper_action_topic_, 1);
00092
00093 close_gripper_ = new GripperClient(gripper_close_topic_, true);
00094 while(!close_gripper_->waitForServer(ros::Duration(5.0))){
00095 ROS_INFO("Waiting for the gripper action server to come up");
00096 }
00097
00098
00099 marker_pub_ = private_nh_.advertise<visualization_msgs::MarkerArray>(marker_topic_, 1);
00100
00101
00102 n = 3;
00103 m = 3;
00104 N = 20;
00105 u0_.setZero(m, N);
00106 VectorT internal_goal(VectorT::Zero(n));
00107
00108 eps_ = 0.02;
00109 max_mov_dist_ = 0.05;
00110
00111 restart_ddp_ = true;
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00123 pr2_arm_ik::setGoal(internal_goal);
00124 bool init_success = DDP_init(&pr2_arm_ik::dynamics, &pr2_arm_ik::dynamicsD, &pr2_arm_ik::cost, &pr2_arm_ik::costD);
00125
00126
00127 obs_ = &pr2_arm_ik::getObstacles();
00128 obs_->clear();
00129
00130
00131 center_.resize(3);
00132 last_goal_.resize(n);
00133 last_pos_.resize(3);
00134 on_way_to_goal_ = false;
00135 last_goal_set_ = false;
00136 last_pos_set_ = false;
00137 curr_t_ = 1;
00138
00139
00140 initialized_ = init_success;
00141 ROS_INFO("Done initializing");
00142 }
00143
00144 ~ArmMPC() {
00145 delete obj_sub_;
00146 delete close_gripper_;
00147 }
00148
00149 void open_gripper(bool wait=false) {
00150 pr2_controllers_msgs::Pr2GripperCommandGoal open;
00151 open.command.position = 0.08;
00152 open.command.max_effort = -1.0;
00153
00154 close_gripper_->sendGoal(open);
00155 if (wait) {
00156 close_gripper_->waitForResult();
00157 if(close_gripper_->getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
00158 ROS_INFO("The gripper opened!");
00159 else
00160 ROS_INFO("The gripper failed to open.");
00161 }
00162 }
00163
00164 void close_gripper(bool wait=false) {
00165 pr2_controllers_msgs::Pr2GripperCommandGoal close;
00166 close.command.position = 0.0;
00167 close.command.max_effort = 20.0;
00168
00169 close_gripper_->sendGoal(close);
00170 if (wait) {
00171 close_gripper_->waitForResult();
00172 if(close_gripper_->getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
00173 ROS_INFO("The gripper closed!");
00174 else
00175 ROS_INFO("The gripper failed to close.");
00176 }
00177 }
00178
00179 void mpc_callback(const motld::TrackedObjectsConstPtr &objects) {
00180 ROS_INFO("mpc_callback called!");
00181 if (not initialized_) {
00182 ROS_WARN("mpc not initialized");
00183 return;
00184 }
00185 if (objects->name.size() < 1) {
00186 ROS_WARN("no object poses received");
00187 return;
00188 }
00189 if (objects->name.size() != objects->pose.poses.size()) {
00190 ROS_WARN("object poses and object names array sizes do not match");
00191 return;
00192 }
00193
00194 if (on_way_to_goal_ && curr_t_ +1 >= curr_traj_.x.cols()) {
00195
00196
00197 }
00198
00199 ros::Time goal_stamp = objects->pose.header.stamp;
00200 ros::Time time_stamp_now = ros::Time::now();
00201
00202 VectorT goal(3);
00203 goal(0) = objects->pose.poses[0].position.x;
00204 goal(1) = objects->pose.poses[0].position.y;
00205 goal(2) = objects->pose.poses[0].position.z;
00206
00207 if (tf_transformer_->waitForTransform(objects->pose.header.frame_id, gripper_frame_, goal_stamp, ros::Duration(1.)) == false) {
00208 ROS_ERROR("Did not find transform between %s and %s", objects->pose.header.frame_id.c_str(), gripper_frame_.c_str());
00209 return;
00210 }
00211 ROS_INFO("Got transform!");
00212
00213 tf::StampedTransform trans;
00214 tf_transformer_->lookupTransform(objects->pose.header.frame_id, gripper_frame_, goal_stamp, trans);
00215
00216
00217 center_(0) = trans.getOrigin().x();
00218 center_(1) = trans.getOrigin().y();
00219 center_(2) = trans.getOrigin().z();
00220
00221
00222 VectorT x0(15);
00223 x0(0) = center_(0) - goal(0);
00224 x0(1) = center_(1) - goal(1);
00225 x0(2) = center_(2) - goal(2);
00226
00227
00228 tf::Vector3 tmp_vec = btVector3(-0.08, -0.1, 0.);
00229
00230 tmp_vec = trans(tmp_vec);
00231 x0(3) = tmp_vec.getX() - goal(0);
00232 x0(4) = tmp_vec.getY() - goal(1);
00233 x0(5) = tmp_vec.getZ() - goal(2);
00234
00235 tmp_vec.setX(-0.08);
00236 tmp_vec.setY(0.1);
00237 tmp_vec.setZ(0.);
00238 tmp_vec = trans(tmp_vec);
00239 x0(6) = tmp_vec.getX() - goal(0);
00240 x0(7) = tmp_vec.getY() - goal(1);
00241 x0(8) = tmp_vec.getZ() - goal(2);
00242
00243 tmp_vec.setX(-0.1);
00244 tmp_vec.setY(0.);
00245 tmp_vec.setZ(0.);
00246 tmp_vec = trans(tmp_vec);
00247 x0(9) = tmp_vec.getX() - goal(0);
00248 x0(10) = tmp_vec.getY() - goal(1);
00249 x0(11) = tmp_vec.getZ() - goal(2);
00250
00251 tmp_vec.setX(-0.2);
00252 tmp_vec.setY(0.);
00253 tmp_vec.setZ(0.);
00254 tmp_vec = trans(tmp_vec);
00255 x0(12) = tmp_vec.getX() - goal(0);
00256 x0(13) = tmp_vec.getY() - goal(1);
00257 x0(14) = tmp_vec.getZ() - goal(2);
00258
00259 if (objects->name.size() > 1) {
00260
00261 obs_->resize(objects->name.size() - 1);
00262 (*obs_)[0].resize(3);
00263 (*obs_)[0](0) = objects->pose.poses[1].position.x - goal(0);
00264 (*obs_)[0](1) = objects->pose.poses[1].position.y - goal(1);
00265 (*obs_)[0](2) = objects->pose.poses[1].position.z - goal(2);
00266 }
00267
00268 float goal_diff = x0.head(3).norm();
00269
00270 if (goal_diff < eps_ + 0.01) {
00271 ROS_INFO("already at goal / goal reached");
00272 close_gripper();
00273 return;
00274 }
00275
00276 float goal_change = 100.;
00277 float pos_change = 100.;
00278 if (last_goal_set_) {
00279 goal_change = (last_goal_ - goal).norm();
00280 }
00281 if (last_pos_set_) {
00282 pos_change = (center_ - last_pos_).norm();
00283 }
00284 ROS_INFO("pchange: %f gchange: %f max_dist: %f", pos_change, goal_change, max_mov_dist_);
00285 if (pos_change > max_mov_dist_ || goal_change > max_mov_dist_) {
00286
00287
00288 on_way_to_goal_ = false;
00289 restart_ddp_ = true;
00290 }
00291
00292
00293
00294 int x_len = curr_traj_.x.cols();
00295
00296 if (false && on_way_to_goal_ && goal_change < eps_ && curr_t_ < x_len - 1) {
00297 curr_t_++;
00298 } else {
00299
00300 if (restart_ddp_) {
00301 ROS_INFO("restarting ddp");
00302 u0_.setZero();
00303 DDP(x0, u0_, params, 100, curr_traj_);
00304 restart_ddp_ = false;
00305 } else {
00306 u0_ = curr_traj_.u;
00307 DDP(x0, u0_, params, 10, curr_traj_);
00308 }
00309 curr_t_ = 1;
00310 }
00311
00312
00313
00314 double dist = (curr_traj_.x.col(curr_t_).head(3) - x0.head(3)).norm();
00315 while (curr_t_ + 1 < curr_traj_.x.cols() && dist < 0.01) {
00316 ++curr_t_;
00317 dist = (curr_traj_.x.col(curr_t_).head(3) - x0.head(3)).norm();
00318 }
00319 ROS_INFO_STREAM("chosen dist = " << dist);
00320 const VectorT &next = curr_traj_.x.col(curr_t_);
00321
00322 gripper_pose_.header.frame_id = objects->pose.header.frame_id;
00323 gripper_pose_.header.stamp = time_stamp_now;
00324 gripper_pose_.pose.position.x = next(0) + goal(0);
00325 gripper_pose_.pose.position.y = next(1) + goal(1);
00326 gripper_pose_.pose.position.z = next(2) + goal(2);
00327
00328
00329
00330 geometry_msgs::QuaternionStamped quat;
00331 quat.header.frame_id = root_frame_;
00332 quat.header.stamp = goal_stamp;
00333
00334 quat.quaternion = tf::createQuaternionMsgFromRollPitchYaw(0., 0., M_PI/2.);
00335
00336
00337 tf_transformer_->transformQuaternion(objects->pose.header.frame_id, quat, quat);
00338 gripper_pose_.pose.orientation = quat.quaternion;
00339
00340
00341 last_goal_ = goal;
00342 last_goal_set_ = true;
00343
00344
00345 last_pos_ = center_;
00346 last_pos_set_ = true;
00347
00348
00349 if (curr_traj_.x.col(curr_traj_.x.cols()-1).norm() < eps_) {
00350 on_way_to_goal_ = true;
00351 } else {
00352 on_way_to_goal_ = false;
00353 }
00354
00355
00356 gripper_pose_pub_.publish(gripper_pose_);
00357 open_gripper();
00358
00359
00360 if (marker_pub_.getNumSubscribers() > 0) {
00361 ROS_INFO("mpc sending markers");
00362 visualization_msgs::MarkerArray markers;
00363 int id = 0;
00364 for (int p = 0; p < curr_traj_.x.cols(); ++p) {
00365 visualization_msgs::Marker marker;
00366 marker.header.frame_id = objects->pose.header.frame_id;
00367 marker.header.stamp = time_stamp_now;
00368 marker.type = marker.SPHERE;
00369 marker.action = marker.ADD;
00370 marker.id = id;
00371 marker.scale.x = 0.02;
00372 marker.scale.y = 0.02;
00373 marker.scale.z = 0.02;
00374 marker.color.a = 1.0;
00375 marker.color.r = 1.0;
00376 marker.color.g = 1.0;
00377 marker.color.b = 0.0;
00378 marker.pose.orientation.w = 1.0;
00379 marker.pose.position.x = curr_traj_.x(0, p) + goal(0);
00380 marker.pose.position.y = curr_traj_.x(1, p) + goal(1);
00381 marker.pose.position.z = curr_traj_.x(2, p) + goal(2);
00382 markers.markers.push_back(marker);
00383 ++id;
00384
00385 marker.color.g = 0.0;
00386 for (int i = 3; i + 3 <= curr_traj_.x.rows(); i+=3) {
00387 marker.id = id;
00388 marker.pose.position.x = curr_traj_.x(i, p) + goal(0);
00389 marker.pose.position.y = curr_traj_.x(i+1, p) + goal(1);
00390 marker.pose.position.z = curr_traj_.x(i+2, p) + goal(2);
00391 markers.markers.push_back(marker);
00392 ++id;
00393 }
00394 }
00395 marker_pub_.publish(markers);
00396 }
00397 }
00398 };
00399
00400 int main(int argc, char *argv[]) {
00401 ros::init(argc, argv, "mpc_node");
00402 ros::NodeHandle n;
00403 ArmMPC mpc_client(n);
00404 while (ros::ok()) {
00405 ros::spinOnce();
00406 }
00407 }