/* void doneCb(const actionlib::SimpleClientGoalState& state, const cwru_action::trajResultConstPtr& result) { ROS_INFO(" doneCb: server responded with state [%s]", state.toString().c_str()); ROS_INFO("got return val = %d", result->return_val); } */ int main(int argc, char** argv) { ros::init(argc, argv, "baxter_cart_move_as"); ros::NodeHandle nh; //standard ros node handle ROS_INFO("instantiating an ArmMotionInterface: "); ArmMotionInterface armMotionInterface(&nh); // start servicing requests: ROS_INFO("ready to start servicing cartesian-space goals"); while (ros::ok()) { ros::spinOnce(); ros::Duration(0.1).sleep(); //don't consume much cpu time if not actively working on a command } return 0; }
int main(int argc, char** argv) { ros::init(argc, argv, "test_cart_path_planner_lib"); ros::NodeHandle nh; //standard ros node handle ROS_INFO("instantiating an ArmMotionInterface: "); ArmMotionInterface armMotionInterface(&nh); //can do this, if needed: A = cartTrajPlanner.get_fk_Affine_from_qvec(Vectorq7x1 q_vec) cout << "instantiating a traj streamer" << endl; // enter 1:"; //cin>>ans; // let the streamer be owned by "main" Baxter_traj_streamer baxter_traj_streamer(&nh); //instantiate a Baxter_traj_streamer object and pass in pointer to nodehandle for constructor to use // warm up the joint-state callbacks; cout << "warming up callbacks..." << endl; for (int i = 0; i < 100; i++) { ros::spinOnce(); //cout<<"spin "<<i<<endl; ros::Duration(0.01).sleep(); } cout << "getting current right-arm pose:" << endl; g_q_vec_right_arm[0] = 1000; while (fabs(g_q_vec_right_arm[0]) > 3) { // keep trying until see viable value populated by fnc g_q_vec_right_arm = baxter_traj_streamer.get_qvec_right_arm(); ros::spinOnce(); ros::Duration(0.01).sleep(); } cout << "r_arm state:" << g_q_vec_right_arm.transpose() << endl; //let's leave this in main: ROS_INFO("instantiating an action client of trajActionServer"); actionlib::SimpleActionClient<baxter_traj_streamer::trajAction> traj_streamer_action_client("trajActionServer", true); // attempt to connect to the server: ROS_INFO("waiting for server trajActionServer: "); bool server_exists = false; while ((!server_exists)&&(ros::ok())) { server_exists = traj_streamer_action_client.waitForServer(ros::Duration(5.0)); // wait for up to 5 seconds ros::spinOnce(); ros::Duration(0.5).sleep(); ROS_INFO("retrying..."); } // something odd in above: does not seem to wait for 5 seconds, but returns rapidly if server not running // if (!server_exists) { // ROS_WARN("could not connect to server; will wait forever"); // return 0; // bail out; optionally, could print a warning message and retry //} //server_exists = action_client.waitForServer(); //wait forever ROS_INFO("connected to action server"); // if here, then we connected to the server; bool unpackok; Eigen::Vector3d delta_p; bool is_valid; bool finished_before_timeout; baxter_traj_streamer::trajGoal goal; Vectorq7x1 q_vec_goal_vq7; //goal pose in joint space, expressed as a 7x1 vector moveit_msgs::DisplayTrajectory display_trajectory; ros::Publisher display_traj_pub = nh.advertise<moveit_msgs::DisplayTrajectory>("/preview_traj", 1, true); // start servicing requests: while (ros::ok()) { g_q_vec_right_arm = baxter_traj_streamer.get_qvec_right_arm(); // update the current sensed arm angles //decide if should start processing a new request: if (armMotionInterface.newRqst()&&!armMotionInterface.isBusy()) { armMotionInterface.setNewRqst(false); //g_received_new_request_=false; // reset trigger to receive a new request armMotionInterface.setIsBusy(true); //g_busy_working_on_a_request_= true; // begin processing new request } if (armMotionInterface.isBusy()) { switch (armMotionInterface.get_cmd_mode()) { case ARM_TEST_MODE: ROS_INFO("responding to request TEST_MODE: "); cout << "unpacking q_vec_start from request message..." << endl; unpackok = armMotionInterface.unpack_qstart(); if (unpackok) { cout << "start qvec rqst: " << armMotionInterface.get_start_qvec().transpose() << endl; } unpackok = armMotionInterface.unpack_qend(); if (unpackok) { cout << "end qvec rqst: " << armMotionInterface.get_end_qvec().transpose() << endl; } //reply w/ populating q_vec_start in response: armMotionInterface.setIsBusy(false); break; case ARM_PLAN_JSPACE_PATH_CURRENT_TO_QGOAL: ROS_INFO("case ARM_PLAN_JSPACE_PATH_CURRENT_TO_QGOAL"); //get the start q_vec = current arm pose: cout << "getting current right-arm pose:" << endl; g_q_vec_right_arm[0] = 1000; //Vectorq7x1 g_q_vec_right_arm; while (fabs(g_q_vec_right_arm[0]) > 3) { // keep trying until see viable value populated by fnc g_q_vec_right_arm = baxter_traj_streamer.get_qvec_right_arm(); ros::spinOnce(); ros::Duration(0.01).sleep(); } //get the goal q_vec, per request message: armMotionInterface.unpack_qend(); q_vec_goal_vq7= armMotionInterface.get_end_qvec(); //need to convert from VectorXd to Vectorq7x1 is_valid = armMotionInterface.plan_jspace_path_qstart_to_qend(g_q_vec_right_arm,q_vec_goal_vq7); if (is_valid) ROS_INFO("computed valid path"); else ROS_INFO("no valid path found"); armMotionInterface.setIsBusy(false); break; case ARM_PLAN_PATH_CURRENT_TO_PRE_POSE: ROS_INFO("responding to request PLAN_PATH_CURRENT_TO_PRE_POSE"); armMotionInterface.plan_path_to_predefined_pre_pose(); armMotionInterface.setIsBusy(false); break; case ARM_PLAN_PATH_CURRENT_TO_GOAL_POSE: cout << "getting current right-arm pose:" << endl; g_q_vec_right_arm[0] = 1000; while (fabs(g_q_vec_right_arm[0]) > 3) { // keep trying until see viable value populated by fnc g_q_vec_right_arm = baxter_traj_streamer.get_qvec_right_arm(); ros::spinOnce(); ros::Duration(0.01).sleep(); } //armMotionInterface.unpack_qstart(); // fills in q_vec_start_rqst_--no...use current arm pose armMotionInterface.unpack_goal_pose(); //fills in a_flange_end_; should check return status // bool plan_path_qstart_to_Agoal(Vectorq7x1 q_start); // provide q_start; assumes use of a_flange_end_ and fills in g_optimal_path is_valid = armMotionInterface.plan_path_qstart_to_Agoal(g_q_vec_right_arm); if (is_valid) ROS_INFO("computed valid path"); else ROS_INFO("no valid path found"); armMotionInterface.setIsBusy(false); break; case ARM_DISPLAY_TRAJECTORY: cout << "getting current joint states:" << endl; g_q_vec_right_arm[0] = 1000; while (fabs(g_q_vec_right_arm[0]) > 3) { // keep trying until see viable value populated by fnc g_q_vec_right_arm = baxter_traj_streamer.get_qvec_right_arm(); ros::spinOnce(); ros::Duration(0.01).sleep(); } //if here, then joint_states_ is valid //populate the moveit message to preview the trajectory plan; //display_trajectory.model_id = "robot_description"; // not sure what goes here; "baxter"?? //declare joint_states_ as start state of display display_trajectory.trajectory_start.joint_state = baxter_traj_streamer.get_joint_states(); // get the joint states from Baxter; baxter_traj_streamer.stuff_trajectory(g_optimal_path, g_des_trajectory);//convert planned path to trajectory display_trajectory.trajectory.resize(1); //display only 1 trajectory display_trajectory.trajectory[0].joint_trajectory = g_des_trajectory; //the one we care about display_traj_pub.publish(display_trajectory); // and publish this to topic "/preview_traj" armMotionInterface.setIsBusy(false); break; case ARM_DESCEND_20CM: ROS_INFO("responding to request DESCEND_20CM"); delta_p << 0, 0, -0.2; //specify delta-p for a 20cm descent // find a joint-space path to do this, holding R fixed cout << "getting current right-arm pose:" << endl; g_q_vec_right_arm[0] = 1000; while (fabs(g_q_vec_right_arm[0]) > 3) { // keep trying until see viable value populated by fnc g_q_vec_right_arm = baxter_traj_streamer.get_qvec_right_arm(); ros::spinOnce(); ros::Duration(0.01).sleep(); } is_valid = armMotionInterface.plan_cartesian_delta_p(g_q_vec_right_arm, delta_p); armMotionInterface.setPathValid(is_valid); armMotionInterface.incrementPathID(); armMotionInterface.setIsBusy(false); break; case ARM_DEPART_20CM: ROS_INFO("responding to request ARM_DEPART_20CM"); delta_p << 0, 0, 0.2; //specify delta-p for a 20cm descent // find a joint-space path to do this, holding R fixed cout << "getting current right-arm pose:" << endl; g_q_vec_right_arm[0] = 1000; while (fabs(g_q_vec_right_arm[0]) > 3) { // keep trying until see viable value populated by fnc g_q_vec_right_arm = baxter_traj_streamer.get_qvec_right_arm(); ros::spinOnce(); ros::Duration(0.01).sleep(); } is_valid = armMotionInterface.plan_cartesian_delta_p(g_q_vec_right_arm, delta_p); armMotionInterface.setPathValid(is_valid); armMotionInterface.incrementPathID(); armMotionInterface.setIsBusy(false); break; //case DEPART_20CM: //case CART_MOVE_DELTA_P: unpack_delta_p()... //case PLAN_PATH_QSTART_TO_ADES: //case PLAN_PATH_QSTART_TO_QGOAL: //case PLAN_PATH_ASTART_TO_QGOAL: case ARM_EXECUTE_PLANNED_PATH: //assumes there is a valid planned path in g_optimal_path ROS_INFO("responding to request EXECUTE_PLANNED_PATH"); if (armMotionInterface.getPathValid()) { // convert path to a trajectory: baxter_traj_streamer.stuff_trajectory(g_optimal_path, g_des_trajectory); //convert from vector of 7dof poses to trajectory message goal.trajectory = g_des_trajectory; ROS_INFO("sending action request to traj streamer node"); traj_streamer_action_client.sendGoal(goal, &doneCb); // we could also name additional callback functions here, if desired // action_client.sendGoal(goal, &doneCb, &activeCb, &feedbackCb); //e.g., like this finished_before_timeout = traj_streamer_action_client.waitForResult(ros::Duration(20.0)); if (!finished_before_timeout) { ROS_WARN("EXECUTE_PLANNED_PATH: giving up waiting on result"); // should set status in service request here... } else { ROS_INFO("finished before timeout"); // should set status in service request here... } } else { ROS_WARN("requested move without valid path! doing nothing"); } armMotionInterface.setIsBusy(false); break; default: ROS_WARN("this command mode is not defined: %d", armMotionInterface.get_cmd_mode()); //clean up/terminate: armMotionInterface.setIsBusy(false); } } ros::spinOnce(); //cout<<"main loop..."<<endl; ros::Duration(0.1).sleep(); //don't consume much cpu time if not actively working on a command } return 0; }