I use `Moveit` pkg to control a robot arm. In a node I detect a chess-board (CB) atteched to the gripper of the arm and publish its `TF` relative to the position of the camera. I want to place a collision object (box) on which is the CB.
The problem appears when the camera looses the chessboard and regains vision over it. In this case the collision box is not placed at the current coordinates of the CB, but to the previously known position and orientation (before the CB was lost from sight). It seams to be that the `planning_scene_interface` does not get the new `TF` coordinates of the CB.
The collision box is created relative to the `/calibration_grid` frame which is actually the chess-board.
How can I "force" the 'planning_scene_interface' to re-check the current frame of the CB and to place there the collision box?
The code:
std::vector ArmControl::creatCollisionObjChessboard(
tf::StampedTransform cameraGrid) {
if (!collisionCB_id.empty())
collisionCB_id.erase(collisionCB_id.begin());
this->collisionBoxesPresent = true;
moveit_msgs::CollisionObject chessBoard_obj;
std::vector collision_objects;
chessBoard_obj.header.frame_id = "calibration_grid";
// The id of the object is used to identify it.
chessBoard_obj.id = "ChessBoard";
// Define a box to add to the world.
shape_msgs::SolidPrimitive primitive;
primitive.type = primitive.BOX;
geometry_msgs::Pose box_pose;
primitive.dimensions.resize(3);
primitive.dimensions[0] = 0.06;
primitive.dimensions[1] = 0.075;
primitive.dimensions[2] = 0.005;
box_pose.orientation.w = 1;
box_pose.orientation.x = 0;
box_pose.orientation.y = 0;
box_pose.orientation.z = 0;
box_pose.position.x = 0.015;
box_pose.position.y = 0.0225;
box_pose.position.z = 0.00;
// collision object parameter setup
chessBoard_obj.primitives.push_back(primitive);
chessBoard_obj.primitive_poses.push_back(box_pose);
chessBoard_obj.operation = chessBoard_obj.ADD;
// add collision object
collision_objects.push_back(chessBoard_obj);
collisionCB_id.push_back(chessBoard_obj.id);
return collision_objects;
}
bool ArmControl::findCB(arm_action_server::FindChessBoard::Request& req,
arm_action_server::FindChessBoard::Response& res) {
int rotation_counter = 0;
bool CBfound = false;
double degrees = 15;
this->current_pos = this->moveToInitialPos();
while (!CBfound)
{
if (this->chessBoard_listener.waitForTransform("/calibration_grid", eef ,ros::Time(0), ros::Duration(1.0))) {
CBfound = true;
} else {
std::cout << "CB not found \n";
rotation_counter++;
this->current_pos = rotateBase(degrees);
}
if (rotation_counter*degrees > 360)
{
this->planning_scene_interface.removeCollisionObjects(this->collisionCB_id);
this->collisionBoxesPresent = false;
sleep(2.0);
return false;
}
}
this->planning_scene_interface.addCollisionObjects(
creatCollisionObjChessboard(transform_cameraToGrid));
sleep(3.0);
res.distance = target_pos.position.y;
res.yaw = target_pos.orientation.z;
res.moveAccomplished = 1.0;
return true;
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "arm_action_server");
ros::NodeHandle nh;
ros::AsyncSpinner spinner(0);
spinner.start();
ArmControl controller;
controller.moveToInitialPos();
ros::ServiceServer findCB_service = nh.advertiseService("find_chess_board",
&ArmControl::findCB, &controller);
ros::ServiceServer flippSW_service = nh.advertiseService("flipp_switch",
&ArmControl::flippSW, &controller);
cout << "Services ON \n \n ";
ros::waitForShutdown();
}
↧