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
00039
00040 #include <youbot_oodl/YouBotOODLWrapper.h>
00041 #include <youbot_oodl/joint_state_observer_oodl.h>
00042
00043 #include <youbot_oodl/youbot_trajectory_action_server/joint_trajectory_action.h>
00044 #include <sstream>
00045
00046 namespace youBot
00047 {
00048
00049 YouBotOODLWrapper::YouBotOODLWrapper()
00050 {
00051 }
00052
00053 YouBotOODLWrapper::YouBotOODLWrapper(ros::NodeHandle n) :
00054 node(n)
00055 {
00056
00057 youBotConfiguration.hasBase = false;
00058 youBotConfiguration.hasArms = false;
00059 areBaseMotorsSwitchedOn = false;
00060 areArmMotorsSwitchedOn = false;
00061
00062 youBotChildFrameID = "base_link";
00063 armJointStateMessages.clear();
00064
00065 n.param("youBotDriverCycleFrequencyInHz", youBotDriverCycleFrequencyInHz, 50.0);
00066
00067
00068
00069 gripperCycleCounter = 0;
00070 diagnosticNameArms = "platform_Arms";
00071 diagnosticNameBase = "platform_Base";
00072 dashboardMessagePublisher = n.advertise < youbot_oodl::PowerBoardState > ("/dashboard/platform_state", 1);
00073 diagnosticArrayPublisher = n.advertise < diagnostic_msgs::DiagnosticArray > ("/diagnostics", 1);
00074 }
00075
00076 YouBotOODLWrapper::~YouBotOODLWrapper()
00077 {
00078 this->stop();
00079 dashboardMessagePublisher.shutdown();
00080 diagnosticArrayPublisher.shutdown();
00081 }
00082
00083 void YouBotOODLWrapper::initializeBase(std::string baseName)
00084 {
00085
00086 try
00087 {
00088 ROS_INFO("Configuration file path: %s", youBotConfiguration.configurationFilePath.c_str());
00089 youBotConfiguration.baseConfiguration.youBotBase = new youbot::YouBotBase(
00090 baseName, youBotConfiguration.configurationFilePath);
00091 youBotConfiguration.baseConfiguration.youBotBase->doJointCommutation();
00092 }
00093 catch (std::exception& e)
00094 {
00095 std::string errorMessage = e.what();
00096 ROS_FATAL("%s", errorMessage.c_str());
00097 ROS_ERROR("Base \"%s\" could not be initialized.", baseName.c_str());
00098 youBotConfiguration.hasBase = false;
00099 return;
00100 }
00101
00102
00103 youBotConfiguration.baseConfiguration.baseCommandSubscriber = node.subscribe("cmd_vel", 1000,
00104 &YouBotOODLWrapper::baseCommandCallback,
00105 this);
00106 youBotConfiguration.baseConfiguration.baseOdometryPublisher = node.advertise < nav_msgs::Odometry > ("odom", 1);
00107 youBotConfiguration.baseConfiguration.baseJointStatePublisher = node.advertise < sensor_msgs::JointState
00108 > ("base/joint_states", 1);
00109
00110
00111 youBotConfiguration.baseConfiguration.switchOffMotorsService = node.advertiseService(
00112 "base/switchOffMotors", &YouBotOODLWrapper::switchOffBaseMotorsCallback, this);
00113 youBotConfiguration.baseConfiguration.switchONMotorsService = node.advertiseService(
00114 "base/switchOnMotors", &YouBotOODLWrapper::switchOnBaseMotorsCallback, this);
00115
00116
00117 youBotOdometryFrameID = "odom";
00118 youBotOdometryChildFrameID = "base_footprint";
00119
00120 ROS_INFO("Base is initialized.");
00121 youBotConfiguration.hasBase = true;
00122 areBaseMotorsSwitchedOn = true;
00123 }
00124
00125 void YouBotOODLWrapper::initializeArm(std::string armName, bool enableStandardGripper)
00126 {
00127 int armIndex;
00128 youbot::JointName jointNameParameter;
00129 std::string jointName;
00130 stringstream topicName;
00131 stringstream serviceName;
00132
00133 try
00134 {
00135 ROS_INFO("Configuration file path: %s", youBotConfiguration.configurationFilePath.c_str());
00136 YouBotArmConfiguration tmpArmConfig;
00137 youBotConfiguration.youBotArmConfigurations.push_back(tmpArmConfig);
00138 armIndex = static_cast<int>(youBotConfiguration.youBotArmConfigurations.size()) - 1;
00139 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm = new youbot::YouBotManipulator(
00140 armName, youBotConfiguration.configurationFilePath);
00141 youBotConfiguration.youBotArmConfigurations[armIndex].armID = armName;
00142 topicName.str("");
00143 topicName << "arm_" << (armIndex + 1) << "/";
00144 youBotConfiguration.youBotArmConfigurations[armIndex].commandTopicName = topicName.str();
00145 youBotConfiguration.youBotArmConfigurations[armIndex].parentFrameIDName = "base_link";
00146 youBotConfiguration.armNameToArmIndexMapping.insert(
00147 make_pair(armName, static_cast<int>(youBotConfiguration.youBotArmConfigurations.size())));
00148
00149
00150 youBotConfiguration.youBotArmConfigurations[armIndex].jointNames.clear();
00151 for (int i = 0; i < youBotArmDoF; ++i)
00152 {
00153 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->getArmJoint(i + 1).getConfigurationParameter(
00154 jointNameParameter);
00155 jointNameParameter.getParameter(jointName);
00156 youBotConfiguration.youBotArmConfigurations[armIndex].jointNames.push_back(jointName);
00157 ROS_INFO("Joint %i for arm %s has name: %s", i + 1,
00158 youBotConfiguration.youBotArmConfigurations[armIndex].armID.c_str(),
00159 youBotConfiguration.youBotArmConfigurations[armIndex].jointNames[i].c_str());
00160
00161 }
00162
00163 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->doJointCommutation();
00164 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->calibrateManipulator();
00165 if (enableStandardGripper)
00166 {
00167 youbot::GripperBarName barName;
00168 std::string gripperBarName;
00169
00170 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->getArmGripper().getGripperBar1().getConfigurationParameter(
00171 barName);
00172 barName.getParameter(gripperBarName);
00173 youBotConfiguration.youBotArmConfigurations[armIndex].gripperFingerNames[YouBotArmConfiguration::LEFT_FINGER_INDEX] =
00174 gripperBarName;
00175 ROS_INFO("Joint %i for gripper of arm %s has name: %s", 1,
00176 youBotConfiguration.youBotArmConfigurations[armIndex].armID.c_str(), gripperBarName.c_str());
00177
00178 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->getArmGripper().getGripperBar2().getConfigurationParameter(
00179 barName);
00180 barName.getParameter(gripperBarName);
00181 youBotConfiguration.youBotArmConfigurations[armIndex].gripperFingerNames[YouBotArmConfiguration::RIGHT_FINGER_INDEX] =
00182 gripperBarName;
00183 ROS_INFO("Joint %i for gripper of arm %s has name: %s", 2,
00184 youBotConfiguration.youBotArmConfigurations[armIndex].armID.c_str(), gripperBarName.c_str());
00185
00186 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->calibrateGripper();
00187 }
00188 }
00189 catch (std::exception& e)
00190 {
00191 youBotConfiguration.youBotArmConfigurations.pop_back();
00192 std::string errorMessage = e.what();
00193 ROS_FATAL("%s", errorMessage.c_str());
00194 ROS_ERROR("Arm \"%s\" could not be initialized.", armName.c_str());
00195 ROS_INFO("System has %i initialized arm(s).", static_cast<int>(youBotConfiguration.youBotArmConfigurations.size()));
00196 return;
00197 }
00198
00199
00200 topicName.str("");
00201 topicName << youBotConfiguration.youBotArmConfigurations[armIndex].commandTopicName
00202 << "arm_controller/position_command";
00203 youBotConfiguration.youBotArmConfigurations[armIndex].armPositionCommandSubscriber = node.subscribe
00204 < brics_actuator::JointPositions
00205 > (topicName.str(), 1000, boost::bind(&YouBotOODLWrapper::armPositionsCommandCallback, this, _1, armIndex));
00206
00207 topicName.str("");
00208 topicName << youBotConfiguration.youBotArmConfigurations[armIndex].commandTopicName
00209 << "arm_controller/velocity_command";
00210 youBotConfiguration.youBotArmConfigurations[armIndex].armVelocityCommandSubscriber = node.subscribe
00211 < brics_actuator::JointVelocities
00212 > (topicName.str(), 1000, boost::bind(&YouBotOODLWrapper::armVelocitiesCommandCallback, this, _1, armIndex));
00213
00214 topicName.str("");
00215 topicName << youBotConfiguration.youBotArmConfigurations[armIndex].commandTopicName
00216 << "arm_controller/follow_joint_trajectory";
00217
00218 youBotConfiguration.youBotArmConfigurations[armIndex].armJointTrajectoryAction = new actionlib::ActionServer<
00219 control_msgs::FollowJointTrajectoryAction>(
00220 node, topicName.str(), boost::bind(&YouBotOODLWrapper::armJointTrajectoryGoalCallback, this, _1, armIndex),
00221 boost::bind(&YouBotOODLWrapper::armJointTrajectoryCancelCallback, this, _1, armIndex), false);
00222
00223 topicName.str("");
00224 topicName << youBotConfiguration.youBotArmConfigurations[armIndex].commandTopicName << "joint_states";
00225 youBotConfiguration.youBotArmConfigurations[armIndex].armJointStatePublisher = node.advertise
00226 < sensor_msgs::JointState > (topicName.str(), 1);
00227
00228 if (enableStandardGripper)
00229 {
00230 topicName.str("");
00231 topicName << youBotConfiguration.youBotArmConfigurations[armIndex].commandTopicName
00232 << "gripper_controller/position_command";
00233 youBotConfiguration.youBotArmConfigurations[armIndex].gripperPositionCommandSubscriber = node.subscribe
00234 < brics_actuator::JointPositions
00235 > (topicName.str(), 1000, boost::bind(&YouBotOODLWrapper::gripperPositionsCommandCallback, this, _1, armIndex));
00236 youBotConfiguration.youBotArmConfigurations[armIndex].lastGripperCommand = 0.0;
00237 }
00238
00239
00240 serviceName.str("");
00241 serviceName << youBotConfiguration.youBotArmConfigurations[armIndex].commandTopicName << "switchOffMotors";
00242 youBotConfiguration.youBotArmConfigurations[armIndex].switchOffMotorsService = node.advertiseService<
00243 std_srvs::Empty::Request, std_srvs::Empty::Response>(
00244 serviceName.str(), boost::bind(&YouBotOODLWrapper::switchOffArmMotorsCallback, this, _1, _2, armIndex));
00245
00246 serviceName.str("");
00247 serviceName << youBotConfiguration.youBotArmConfigurations[armIndex].commandTopicName << "switchOnMotors";
00248 youBotConfiguration.youBotArmConfigurations[armIndex].switchONMotorsService = node.advertiseService<
00249 std_srvs::Empty::Request, std_srvs::Empty::Response>(
00250 serviceName.str(), boost::bind(&YouBotOODLWrapper::switchOnArmMotorsCallback, this, _1, _2, armIndex));
00251
00252 serviceName.str("");
00253 serviceName << youBotConfiguration.youBotArmConfigurations[armIndex].commandTopicName << "calibrate";
00254 youBotConfiguration.youBotArmConfigurations[armIndex].calibrateService = node.advertiseService<
00255 std_srvs::Empty::Request, std_srvs::Empty::Response>(
00256 serviceName.str(), boost::bind(&YouBotOODLWrapper::calibrateArmCallback, this, _1, _2, armIndex));
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 sensor_msgs::JointState dummyMessage;
00279 armJointStateMessages.push_back(dummyMessage);
00280
00281
00282 youBotArmFrameID = "arm";
00283 ROS_INFO("Arm \"%s\" is initialized.", armName.c_str());
00284 ROS_INFO("System has %i initialized arm(s).", static_cast<int>(youBotConfiguration.youBotArmConfigurations.size()));
00285 youBotConfiguration.hasArms = true;
00286 areArmMotorsSwitchedOn = true;
00287
00288
00289 armHasActiveJointTrajectoryGoal = false;
00290
00291
00292
00293
00294
00295 youBotConfiguration.youBotArmConfigurations[armIndex].armJointTrajectoryAction->start();
00296 }
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 void YouBotOODLWrapper::stop()
00311 {
00312
00313 if (youBotConfiguration.baseConfiguration.youBotBase)
00314 {
00315 delete youBotConfiguration.baseConfiguration.youBotBase;
00316 youBotConfiguration.baseConfiguration.youBotBase = 0;
00317 }
00318
00319 youBotConfiguration.baseConfiguration.baseCommandSubscriber.shutdown();
00320 youBotConfiguration.baseConfiguration.baseJointStatePublisher.shutdown();
00321 youBotConfiguration.baseConfiguration.baseOdometryPublisher.shutdown();
00322 youBotConfiguration.baseConfiguration.switchONMotorsService.shutdown();
00323 youBotConfiguration.baseConfiguration.switchOffMotorsService.shutdown();
00324
00325 youBotConfiguration.hasBase = false;
00326 areBaseMotorsSwitchedOn = false;
00327
00328 for (int armIndex = 0; armIndex < static_cast<int>(youBotConfiguration.youBotArmConfigurations.size()); armIndex++)
00329 {
00330 if (youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm)
00331 {
00332 delete youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm;
00333 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm = 0;
00334 }
00335
00336 youBotConfiguration.youBotArmConfigurations[armIndex].armJointStatePublisher.shutdown();
00337 youBotConfiguration.youBotArmConfigurations[armIndex].armPositionCommandSubscriber.shutdown();
00338 youBotConfiguration.youBotArmConfigurations[armIndex].armVelocityCommandSubscriber.shutdown();
00339 youBotConfiguration.youBotArmConfigurations[armIndex].calibrateService.shutdown();
00340 youBotConfiguration.youBotArmConfigurations[armIndex].gripperPositionCommandSubscriber.shutdown();
00341 youBotConfiguration.youBotArmConfigurations[armIndex].switchONMotorsService.shutdown();
00342 youBotConfiguration.youBotArmConfigurations[armIndex].switchOffMotorsService.shutdown();
00343 }
00344
00345 youBotConfiguration.hasArms = false;
00346 areArmMotorsSwitchedOn = false;
00347 youBotConfiguration.youBotArmConfigurations.clear();
00348 armJointStateMessages.clear();
00349
00350 youbot::EthercatMaster::destroy();
00351 }
00352
00353 void YouBotOODLWrapper::baseCommandCallback(const geometry_msgs::Twist& youbotBaseCommand)
00354 {
00355
00356 if (youBotConfiguration.hasBase)
00357 {
00358 quantity < si::velocity > longitudinalVelocity;
00359 quantity < si::velocity > transversalVelocity;
00360 quantity < si::angular_velocity > angularVelocity;
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 longitudinalVelocity = youbotBaseCommand.linear.x * meter_per_second;
00381 transversalVelocity = youbotBaseCommand.linear.y * meter_per_second;
00382 angularVelocity = youbotBaseCommand.angular.z * radian_per_second;
00383
00384 try
00385 {
00386 youBotConfiguration.baseConfiguration.youBotBase->setBaseVelocity(longitudinalVelocity, transversalVelocity,
00387 angularVelocity);
00388 }
00389 catch (std::exception& e)
00390 {
00391 std::string errorMessage = e.what();
00392 ROS_WARN("Cannot set base velocities: %s", errorMessage.c_str());
00393 }
00394
00395 }
00396 else
00397 {
00398 ROS_ERROR("No base initialized!");
00399 }
00400 }
00401
00402 void YouBotOODLWrapper::armPositionsCommandCallback(const brics_actuator::JointPositionsConstPtr& youbotArmCommand,
00403 int armIndex)
00404 {
00405 ROS_DEBUG("Command for arm%i received", armIndex + 1);
00406 ROS_ASSERT(0 <= armIndex && armIndex < static_cast<int>(youBotConfiguration.youBotArmConfigurations.size()));
00407
00408 if (youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm != 0)
00409 {
00410
00411 ROS_DEBUG("Arm ID is: %s", youBotConfiguration.youBotArmConfigurations[armIndex].armID.c_str());
00412 if (youbotArmCommand->positions.size() < 1)
00413 {
00414 ROS_WARN("youBot driver received an invalid joint positions command.");
00415 return;
00416 }
00417
00418 youbot::JointAngleSetpoint desiredAngle;
00419 string unit = boost::units::to_string(boost::units::si::radian);
00420
00421
00422 std::map<string, double> jointNameToValueMapping;
00423 for (int i = 0; i < static_cast<int>(youbotArmCommand->positions.size()); ++i)
00424 {
00425 if (unit == youbotArmCommand->positions[i].unit)
00426 {
00427 jointNameToValueMapping.insert(
00428 make_pair(youbotArmCommand->positions[i].joint_uri, youbotArmCommand->positions[i].value));
00429 }
00430 else
00431 {
00432 ROS_WARN("Unit incompatibility. Are you sure you want to command %s instead of %s ?",
00433 youbotArmCommand->positions[i].unit.c_str(), unit.c_str());
00434 }
00435 }
00436
00437
00438 ROS_ASSERT(
00439 youBotConfiguration.youBotArmConfigurations[armIndex].jointNames.size()
00440 == static_cast<unsigned int>(youBotArmDoF));
00441 youbot::EthercatMaster::getInstance().AutomaticSendOn(false);
00442 for (int i = 0; i < youBotArmDoF; ++i)
00443 {
00444
00445
00446 map<string, double>::const_iterator jointIterator = jointNameToValueMapping.find(
00447 youBotConfiguration.youBotArmConfigurations[armIndex].jointNames[i]);
00448 if (jointIterator != jointNameToValueMapping.end())
00449 {
00450
00451
00452 ROS_DEBUG("Trying to set joint %s to new position value %f",
00453 (youBotConfiguration.youBotArmConfigurations[armIndex].jointNames[i]).c_str(), jointIterator->second);
00454 desiredAngle.angle = jointIterator->second * radian;
00455 try
00456 {
00457 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->getArmJoint(i + 1).setData(desiredAngle);
00458 }
00459 catch (std::exception& e)
00460 {
00461 std::string errorMessage = e.what();
00462 ROS_WARN("Cannot set arm joint %i: %s", i + 1, errorMessage.c_str());
00463 }
00464 }
00465 }
00466 youbot::EthercatMaster::getInstance().AutomaticSendOn(true);
00467 }
00468 else
00469 {
00470 ROS_ERROR("Arm%i is not correctly initialized!", armIndex + 1);
00471 }
00472
00473 }
00474
00475 void YouBotOODLWrapper::armVelocitiesCommandCallback(const brics_actuator::JointVelocitiesConstPtr& youbotArmCommand,
00476 int armIndex)
00477 {
00478 ROS_DEBUG("Command for arm%i received", armIndex + 1);
00479 ROS_ASSERT(0 <= armIndex && armIndex < static_cast<int>(youBotConfiguration.youBotArmConfigurations.size()));
00480
00481 if (youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm != 0)
00482 {
00483
00484 if (youbotArmCommand->velocities.size() < 1)
00485 {
00486 ROS_WARN("youBot driver received an invalid joint velocities command.");
00487 return;
00488 }
00489
00490 youbot::JointVelocitySetpoint desiredAngularVelocity;
00491 string unit = boost::units::to_string(boost::units::si::radian_per_second);
00492
00493
00494 std::map<string, double> jointNameToValueMapping;
00495 for (int i = 0; i < static_cast<int>(youbotArmCommand->velocities.size()); ++i)
00496 {
00497 if (unit == youbotArmCommand->velocities[i].unit)
00498 {
00499 jointNameToValueMapping.insert(
00500 make_pair(youbotArmCommand->velocities[i].joint_uri, youbotArmCommand->velocities[i].value));
00501 }
00502 else
00503 {
00504 ROS_WARN("Unit incompatibility. Are you sure you want to command %s instead of %s ?",
00505 youbotArmCommand->velocities[i].unit.c_str(), unit.c_str());
00506 }
00507
00508 }
00509
00510
00511 ROS_ASSERT(
00512 youBotConfiguration.youBotArmConfigurations[armIndex].jointNames.size()
00513 == static_cast<unsigned int>(youBotArmDoF));
00514 youbot::EthercatMaster::getInstance().AutomaticSendOn(false);
00515 for (int i = 0; i < youBotArmDoF; ++i)
00516 {
00517
00518
00519 map<string, double>::const_iterator jointIterator = jointNameToValueMapping.find(
00520 youBotConfiguration.youBotArmConfigurations[armIndex].jointNames[i]);
00521 if (jointIterator != jointNameToValueMapping.end())
00522 {
00523
00524
00525 ROS_DEBUG("Trying to set joint %s to new velocity value %f",
00526 (youBotConfiguration.youBotArmConfigurations[armIndex].jointNames[i]).c_str(), jointIterator->second);
00527 desiredAngularVelocity.angularVelocity = jointIterator->second * radian_per_second;
00528 try
00529 {
00530 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->getArmJoint(i + 1).setData(
00531 desiredAngularVelocity);
00532
00533 }
00534 catch (std::exception& e)
00535 {
00536 std::string errorMessage = e.what();
00537 ROS_WARN("Cannot set arm joint %i: %s", i + 1, errorMessage.c_str());
00538 }
00539 }
00540 }
00541 youbot::EthercatMaster::getInstance().AutomaticSendOn(true);
00542 }
00543 else
00544 {
00545 ROS_ERROR("Arm%i is not correctly initialized!", armIndex + 1);
00546 }
00547 }
00548
00549 void YouBotOODLWrapper::armJointTrajectoryGoalCallback(
00550 actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::GoalHandle youbotArmGoal, unsigned int armIndex)
00551 {
00552 ROS_INFO("Goal for arm%i received", armIndex + 1);
00553 ROS_ASSERT(armIndex < youBotConfiguration.youBotArmConfigurations.size());
00554
00555 if (youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm == 0)
00556 {
00557 ROS_ERROR("Arm%i is not correctly initialized!", armIndex + 1);
00558 youbotArmGoal.setRejected();
00559 return;
00560 }
00561
00562 trajectory_msgs::JointTrajectory trajectory = youbotArmGoal.getGoal()->trajectory;
00563
00564
00565 if (trajectory.joint_names.size() != static_cast<unsigned int>(youBotArmDoF))
00566 {
00567 ROS_ERROR("Trajectory is malformed! Goal has %i joint names, but only %i joints are supported",
00568 static_cast<int>(trajectory.joint_names.size()), youBotArmDoF);
00569 youbotArmGoal.setRejected();
00570 return;
00571 }
00572
00573
00574 for (unsigned int i = 0; i < youBotConfiguration.youBotArmConfigurations[armIndex].jointNames.size(); i++)
00575 {
00576 bool jointNameFound = false;
00577 for (unsigned int j = 0; j < trajectory.joint_names.size(); j++)
00578 {
00579 if (youBotConfiguration.youBotArmConfigurations[armIndex].jointNames[i] == trajectory.joint_names[j])
00580 {
00581 jointNameFound = true;
00582 break;
00583 }
00584 }
00585
00586 if (!jointNameFound)
00587 {
00588 ROS_ERROR("Trajectory is malformed! Joint %s is missing in the goal",
00589 youBotConfiguration.youBotArmConfigurations[armIndex].jointNames[i].c_str());
00590 youbotArmGoal.setRejected();
00591 return;
00592 }
00593 }
00594
00595 std::vector < youbot::JointTrajectory > jointTrajectories(youBotArmDoF);
00596
00597
00598 std::vector < std::vector<quantity<plane_angle> > > positions(youBotArmDoF);
00599 std::vector < std::vector<quantity<angular_velocity> > > velocities(youBotArmDoF);
00600 std::vector < std::vector<quantity<angular_acceleration> > > accelerations(youBotArmDoF);
00601 youbot::TrajectorySegment segment;
00602 for (unsigned int i = 0; i < trajectory.points.size(); i++)
00603 {
00604 trajectory_msgs::JointTrajectoryPoint point = trajectory.points[i];
00605
00606 if ((point.positions.size() != static_cast<unsigned int>(youBotArmDoF)
00607 || point.velocities.size() != static_cast<unsigned int>(youBotArmDoF)
00608 || point.accelerations.size() != static_cast<unsigned int>(youBotArmDoF)))
00609 {
00610 ROS_ERROR("A trajectory point is malformed! %i positions, velocities and accelerations must be provided",
00611 youBotArmDoF);
00612 youbotArmGoal.setRejected();
00613 return;
00614 }
00615
00616 for (int j = 0; j < youBotArmDoF; j++)
00617 {
00618 segment.positions = point.positions[j] * radian;
00619 segment.velocities = point.velocities[j] * radian_per_second;
00620 segment.accelerations = point.accelerations[j] * radian_per_second / second;
00621 segment.time_from_start = boost::posix_time::microsec(point.time_from_start.toNSec() / 1000);
00622 jointTrajectories[j].segments.push_back(segment);
00623 }
00624 }
00625 for (int j = 0; j < youBotArmDoF; j++)
00626 {
00627 jointTrajectories[j].start_time = boost::posix_time::microsec_clock::local_time();
00628 }
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642 youbotArmGoal.setAccepted();
00643 armActiveJointTrajectoryGoal = youbotArmGoal;
00644 armHasActiveJointTrajectoryGoal = true;
00645
00646
00647
00648
00649 for (int i = 0; i < youBotArmDoF; ++i)
00650 {
00651 try
00652 {
00653
00654 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->getArmJoint(i + 1).trajectoryController.setTrajectory(
00655 jointTrajectories[i]);
00656 ROS_INFO("set trajectories %d", i);
00657 }
00658 catch (std::exception& e)
00659 {
00660 std::string errorMessage = e.what();
00661 ROS_WARN("Cannot set trajectory for joint %i: %s", i + 1, errorMessage.c_str());
00662 }
00663 }
00664 ROS_INFO("set all trajectories");
00665 }
00666
00667 void YouBotOODLWrapper::armJointTrajectoryCancelCallback(
00668 actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::GoalHandle youbotArmGoal, unsigned int armIndex)
00669 {
00670 ROS_DEBUG("Goal for arm%i received", armIndex + 1);
00671 ROS_ASSERT(armIndex < youBotConfiguration.youBotArmConfigurations.size());
00672
00673
00674 for (int i = 0; i < youBotArmDoF; ++i)
00675 {
00676 try
00677 {
00678
00679
00680 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->getArmJoint(i + 1).trajectoryController.cancelCurrentTrajectory();
00681 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->getArmJoint(i + 1).stopJoint();
00682 }
00683 catch (std::exception& e)
00684 {
00685 std::string errorMessage = e.what();
00686 ROS_WARN("Cannot stop joint %i: %s", i + 1, errorMessage.c_str());
00687 }
00688 }
00689
00690 if (armActiveJointTrajectoryGoal == youbotArmGoal)
00691 {
00692
00693 youbotArmGoal.setCanceled();
00694 armHasActiveJointTrajectoryGoal = false;
00695 }
00696 }
00697
00698 void YouBotOODLWrapper::gripperPositionsCommandCallback(
00699 const brics_actuator::JointPositionsConstPtr& youbotGripperCommand, int armIndex)
00700 {
00701 ROS_DEBUG("Command for gripper%i received", armIndex + 1);
00702 ROS_ASSERT(0 <= armIndex && armIndex < static_cast<int>(youBotConfiguration.youBotArmConfigurations.size()));
00703
00704 if (youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm != 0)
00705 {
00706
00707 if (youbotGripperCommand->positions.size() < 1)
00708 {
00709 ROS_WARN("youBot driver received an invalid gripper positions command.");
00710 return;
00711 }
00712
00713 map<string, double>::const_iterator gripperIterator;
00714 youbot::GripperBarPositionSetPoint leftGripperFingerPosition;
00715 youbot::GripperBarPositionSetPoint rightGripperFingerPosition;
00716 string unit = boost::units::to_string(boost::units::si::meter);
00717
00718
00719 std::map<string, double> jointNameToValueMapping;
00720 for (int i = 0; i < static_cast<int>(youbotGripperCommand->positions.size()); ++i)
00721 {
00722 if (unit == youbotGripperCommand->positions[i].unit)
00723 {
00724 jointNameToValueMapping.insert(
00725 make_pair(youbotGripperCommand->positions[i].joint_uri, youbotGripperCommand->positions[i].value));
00726 }
00727 else
00728 {
00729 ROS_WARN("Unit incompatibility. Are you sure you want to command %s instead of %s ?",
00730 youbotGripperCommand->positions[i].unit.c_str(), unit.c_str());
00731 }
00732 }
00733
00734 youbot::EthercatMaster::getInstance().AutomaticSendOn(false);
00735
00736
00737 gripperIterator =
00738 jointNameToValueMapping.find(
00739 youBotConfiguration.youBotArmConfigurations[armIndex].gripperFingerNames[YouBotArmConfiguration::LEFT_FINGER_INDEX]);
00740 if (gripperIterator != jointNameToValueMapping.end())
00741 {
00742 ROS_DEBUG("Trying to set the left gripper finger to new value %f", gripperIterator->second);
00743
00744 leftGripperFingerPosition.barPosition = gripperIterator->second * meter;
00745 try
00746 {
00747 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->getArmGripper().getGripperBar1().setData(
00748 leftGripperFingerPosition);
00749 }
00750 catch (std::exception& e)
00751 {
00752 std::string errorMessage = e.what();
00753 ROS_WARN("Cannot set the left gripper finger: %s", errorMessage.c_str());
00754 }
00755 }
00756
00757
00758 gripperIterator =
00759 jointNameToValueMapping.find(
00760 youBotConfiguration.youBotArmConfigurations[armIndex].gripperFingerNames[YouBotArmConfiguration::RIGHT_FINGER_INDEX]);
00761 if (gripperIterator != jointNameToValueMapping.end())
00762 {
00763 ROS_DEBUG("Trying to set the right gripper to new value %f", gripperIterator->second);
00764
00765 rightGripperFingerPosition.barPosition = gripperIterator->second * meter;
00766 try
00767 {
00768 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->getArmGripper().getGripperBar2().setData(
00769 rightGripperFingerPosition);
00770 }
00771 catch (std::exception& e)
00772 {
00773 std::string errorMessage = e.what();
00774 ROS_WARN("Cannot set the right gripper finger: %s", errorMessage.c_str());
00775 }
00776 }
00777
00778 youbot::EthercatMaster::getInstance().AutomaticSendOn(true);
00779 }
00780 else
00781 {
00782 ROS_ERROR("Arm%i is not correctly initialized!", armIndex + 1);
00783 }
00784 }
00785
00786 void YouBotOODLWrapper::computeOODLSensorReadings()
00787 {
00788
00789 try
00790 {
00791 currentTime = ros::Time::now();
00792 youbot::JointSensedAngle currentAngle;
00793 youbot::JointSensedVelocity currentVelocity;
00794
00795 youbot::EthercatMaster::getInstance().AutomaticReceiveOn(false);
00796
00797 if (youBotConfiguration.hasBase == true)
00798 {
00799 double x = 0.0;
00800 double y = 0.0;
00801 double theta = 0.0;
00802
00803 double vx = 0.0;
00804 double vy = 0.0;
00805 double vtheta = 0.0;
00806
00807 quantity < si::length > longitudinalPosition;
00808 quantity < si::length > transversalPosition;
00809 quantity < plane_angle > orientation;
00810
00811 quantity < si::velocity > longitudinalVelocity;
00812 quantity < si::velocity > transversalVelocity;
00813 quantity < si::angular_velocity > angularVelocity;
00814
00815 youBotConfiguration.baseConfiguration.youBotBase->getBasePosition(longitudinalPosition, transversalPosition,
00816 orientation);
00817 x = longitudinalPosition.value();
00818 y = transversalPosition.value();
00819 theta = orientation.value();
00820
00821 youBotConfiguration.baseConfiguration.youBotBase->getBaseVelocity(longitudinalVelocity, transversalVelocity,
00822 angularVelocity);
00823 vx = longitudinalVelocity.value();
00824 vy = transversalVelocity.value();
00825 vtheta = angularVelocity.value();
00826
00827
00828
00829 odometryQuaternion = tf::createQuaternionMsgFromYaw(theta);
00830
00831 odometryTransform.header.stamp = currentTime;
00832 odometryTransform.header.frame_id = youBotOdometryFrameID;
00833 odometryTransform.child_frame_id = youBotOdometryChildFrameID;
00834
00835 odometryTransform.transform.translation.x = x;
00836 odometryTransform.transform.translation.y = y;
00837 odometryTransform.transform.translation.z = 0.0;
00838 odometryTransform.transform.rotation = odometryQuaternion;
00839
00840
00841 odometryMessage.header.stamp = currentTime;
00842 odometryMessage.header.frame_id = youBotOdometryFrameID;
00843
00844 odometryMessage.pose.pose.position.x = x;
00845 odometryMessage.pose.pose.position.y = y;
00846 odometryMessage.pose.pose.position.z = 0.0;
00847 odometryMessage.pose.pose.orientation = odometryQuaternion;
00848
00849 odometryMessage.child_frame_id = youBotOdometryChildFrameID;
00850
00851 odometryMessage.twist.twist.linear.x = vx;
00852 odometryMessage.twist.twist.linear.y = vy;
00853 odometryMessage.twist.twist.angular.z = vtheta;
00854
00855
00856 baseJointStateMessage.header.stamp = currentTime;
00857 baseJointStateMessage.name.resize(youBotNumberOfWheels * 2);
00858 baseJointStateMessage.position.resize(youBotNumberOfWheels * 2);
00859 baseJointStateMessage.velocity.resize(youBotNumberOfWheels * 2);
00860
00861 ROS_ASSERT(
00862 (youBotConfiguration.baseConfiguration.wheelNames.size() == static_cast<unsigned int>(youBotNumberOfWheels)));
00863 for (int i = 0; i < youBotNumberOfWheels; ++i)
00864 {
00865 youBotConfiguration.baseConfiguration.youBotBase->getBaseJoint(i + 1).getData(currentAngle);
00866 youBotConfiguration.baseConfiguration.youBotBase->getBaseJoint(i + 1).getData(currentVelocity);
00867
00868 baseJointStateMessage.name[i] = youBotConfiguration.baseConfiguration.wheelNames[i];
00869 baseJointStateMessage.position[i] = currentAngle.angle.value();
00870 baseJointStateMessage.velocity[i] = currentVelocity.angularVelocity.value();
00871 }
00872
00873
00874
00875
00876
00877 baseJointStateMessage.name[4] = "caster_joint_fl";
00878 baseJointStateMessage.position[4] = 0.0;
00879
00880 baseJointStateMessage.name[5] = "caster_joint_fr";
00881 baseJointStateMessage.position[5] = 0.0;
00882
00883 baseJointStateMessage.name[6] = "caster_joint_bl";
00884 baseJointStateMessage.position[6] = 0.0;
00885
00886 baseJointStateMessage.name[7] = "caster_joint_br";
00887 baseJointStateMessage.position[7] = 0.0;
00888
00889
00890
00891
00892
00893
00894 baseJointStateMessage.position[0] = -baseJointStateMessage.position[0];
00895 baseJointStateMessage.position[2] = -baseJointStateMessage.position[2];
00896
00897 }
00898
00899 if (youBotConfiguration.hasArms == true)
00900 {
00901
00902 for (int armIndex = 0; armIndex < static_cast<int>(youBotConfiguration.youBotArmConfigurations.size());
00903 armIndex++)
00904 {
00905 ROS_ASSERT(youBotConfiguration.youBotArmConfigurations.size() == armJointStateMessages.size());
00906
00907
00908 armJointStateMessages[armIndex].header.stamp = currentTime;
00909 armJointStateMessages[armIndex].name.resize(youBotArmDoF + youBotNumberOfFingers);
00910 armJointStateMessages[armIndex].position.resize(youBotArmDoF + youBotNumberOfFingers);
00911 armJointStateMessages[armIndex].velocity.resize(youBotArmDoF + youBotNumberOfFingers);
00912
00913 if (youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm == 0)
00914 {
00915 ROS_ERROR("Arm%i is not correctly initialized! Cannot publish data.", armIndex + 1);
00916 continue;
00917 }
00918
00919 ROS_ASSERT(
00920 youBotConfiguration.youBotArmConfigurations[armIndex].jointNames.size()
00921 == static_cast<unsigned int>(youBotArmDoF));
00922 for (int i = 0; i < youBotArmDoF; ++i)
00923 {
00924 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->getArmJoint(i + 1).getData(currentAngle);
00925 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->getArmJoint(i + 1).getData(currentVelocity);
00926
00927 armJointStateMessages[armIndex].name[i] = youBotConfiguration.youBotArmConfigurations[armIndex].jointNames[i];
00928 armJointStateMessages[armIndex].position[i] = currentAngle.angle.value();
00929 armJointStateMessages[armIndex].velocity[i] = currentVelocity.angularVelocity.value();
00930 }
00931
00932
00933 bool areTrajectoryControllersDone = true;
00934 for (int i = 0; i < youBotArmDoF; ++i)
00935 {
00936 if (youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->getArmJoint(i + 1).trajectoryController.isTrajectoryControllerActive())
00937 {
00938 areTrajectoryControllersDone = false;
00939 break;
00940 }
00941 }
00942 if (areTrajectoryControllersDone && armHasActiveJointTrajectoryGoal)
00943 {
00944 armHasActiveJointTrajectoryGoal = false;
00945 control_msgs::FollowJointTrajectoryResult trajectoryResult;
00946 trajectoryResult.error_code = trajectoryResult.SUCCESSFUL;
00947 armActiveJointTrajectoryGoal.setSucceeded(trajectoryResult, "trajectory successful");
00948
00949
00950
00951 }
00952
00953
00954
00955
00956
00957
00958
00959 try
00960 {
00961 youbot::YouBotGripperBar& gripperBar1 =
00962 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->getArmGripper().getGripperBar1();
00963 youbot::YouBotGripperBar& gripperBar2 =
00964 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->getArmGripper().getGripperBar2();
00965
00966 if (gripperCycleCounter == 0)
00967 {
00968 gripperCycleCounter = youBotDriverCycleFrequencyInHz / 5;
00969 gripperBar1.getData(gripperBar1Position);
00970 gripperBar2.getData(gripperBar2Position);
00971 }
00972 gripperCycleCounter--;
00973
00974 armJointStateMessages[armIndex].name[youBotArmDoF + 0] =
00975 youBotConfiguration.youBotArmConfigurations[armIndex].gripperFingerNames[YouBotArmConfiguration::LEFT_FINGER_INDEX];
00976 double leftGipperFingerPosition = gripperBar1Position.barPosition.value();
00977 armJointStateMessages[armIndex].position[youBotArmDoF + 0] = leftGipperFingerPosition;
00978
00979 double rightGipperFingerPosition = gripperBar2Position.barPosition.value();
00980 armJointStateMessages[armIndex].name[youBotArmDoF + 1] =
00981 youBotConfiguration.youBotArmConfigurations[armIndex].gripperFingerNames[YouBotArmConfiguration::RIGHT_FINGER_INDEX];
00982 armJointStateMessages[armIndex].position[youBotArmDoF + 1] = rightGipperFingerPosition;
00983 }
00984 catch (std::exception& e)
00985 {
00986 std::string errorMessage = e.what();
00987 ROS_WARN("Cannot read gripper values: %s", errorMessage.c_str());
00988 }
00989
00990
00991
00992
00993
00994
00995
00996 }
00997 }
00998
00999 youbot::EthercatMaster::getInstance().AutomaticReceiveOn(true);
01000 }
01001 catch (youbot::EtherCATConnectionException& e)
01002 {
01003 ROS_WARN("%s", e.what());
01004 youBotConfiguration.hasBase = false;
01005 youBotConfiguration.hasArms = false;
01006 }
01007 catch (std::exception& e)
01008 {
01009 ROS_WARN_ONCE("%s", e.what());
01010 }
01011
01012 }
01013
01014 void YouBotOODLWrapper::publishOODLSensorReadings()
01015 {
01016
01017 if (youBotConfiguration.hasBase)
01018 {
01019 youBotConfiguration.baseConfiguration.odometryBroadcaster.sendTransform(odometryTransform);
01020 youBotConfiguration.baseConfiguration.baseOdometryPublisher.publish(odometryMessage);
01021 youBotConfiguration.baseConfiguration.baseJointStatePublisher.publish(baseJointStateMessage);
01022 }
01023
01024 if (youBotConfiguration.hasArms)
01025 {
01026 for (int armIndex = 0; armIndex < static_cast<int>(youBotConfiguration.youBotArmConfigurations.size()); armIndex++)
01027 {
01028 youBotConfiguration.youBotArmConfigurations[armIndex].armJointStatePublisher.publish(
01029 armJointStateMessages[armIndex]);
01030 }
01031 }
01032
01033 }
01034
01035 bool YouBotOODLWrapper::switchOffBaseMotorsCallback(std_srvs::Empty::Request& request,
01036 std_srvs::Empty::Response& response)
01037 {
01038 ROS_INFO("Switch off the base motors");
01039 if (youBotConfiguration.hasBase)
01040 {
01041
01042 youbot::JointCurrentSetpoint currentStopMovement;
01043 currentStopMovement.current = 0.0 * ampere;
01044 try
01045 {
01046 youbot::EthercatMaster::getInstance().AutomaticSendOn(false);
01047 youBotConfiguration.baseConfiguration.youBotBase->getBaseJoint(1).setData(currentStopMovement);
01048 youBotConfiguration.baseConfiguration.youBotBase->getBaseJoint(2).setData(currentStopMovement);
01049 youBotConfiguration.baseConfiguration.youBotBase->getBaseJoint(3).setData(currentStopMovement);
01050 youBotConfiguration.baseConfiguration.youBotBase->getBaseJoint(4).setData(currentStopMovement);
01051 youbot::EthercatMaster::getInstance().AutomaticSendOn(true);
01052 }
01053 catch (std::exception& e)
01054 {
01055 std::string errorMessage = e.what();
01056 ROS_WARN("Cannot switch off the base motors: %s", errorMessage.c_str());
01057 return false;
01058 }
01059 }
01060 else
01061 {
01062 ROS_ERROR("No base initialized!");
01063 return false;
01064 }
01065 areBaseMotorsSwitchedOn = false;
01066 return true;
01067 }
01068
01069 bool YouBotOODLWrapper::switchOnBaseMotorsCallback(std_srvs::Empty::Request& request,
01070 std_srvs::Empty::Response& response)
01071 {
01072 ROS_INFO("Switch on the base motors");
01073 if (youBotConfiguration.hasBase)
01074 {
01075 quantity < si::velocity > longitudinalVelocity;
01076 quantity < si::velocity > transversalVelocity;
01077 quantity < si::angular_velocity > angularVelocity;
01078
01079 longitudinalVelocity = 0.0 * meter_per_second;
01080 transversalVelocity = 0.0 * meter_per_second;
01081 angularVelocity = 0.0 * radian_per_second;
01082
01083 try
01084 {
01085 youBotConfiguration.baseConfiguration.youBotBase->setBaseVelocity(longitudinalVelocity, transversalVelocity,
01086 angularVelocity);
01087 }
01088 catch (std::exception& e)
01089 {
01090 std::string errorMessage = e.what();
01091 ROS_WARN("Cannot set base velocities: %s", errorMessage.c_str());
01092 return false;
01093 }
01094 }
01095 else
01096 {
01097 ROS_ERROR("No base initialized!");
01098 return false;
01099 }
01100 areBaseMotorsSwitchedOn = true;
01101 return true;
01102 }
01103
01104 bool YouBotOODLWrapper::switchOffArmMotorsCallback(std_srvs::Empty::Request& request,
01105 std_srvs::Empty::Response& response, int armIndex)
01106 {
01107 ROS_INFO("Switch off the arm%i motors", armIndex + 1);
01108 ROS_ASSERT(0 <= armIndex && armIndex < static_cast<int>(youBotConfiguration.youBotArmConfigurations.size()));
01109
01110 if (youBotConfiguration.hasArms && youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm != 0)
01111 {
01112
01113 youbot::JointCurrentSetpoint currentStopMovement;
01114 currentStopMovement.current = 0.0 * ampere;
01115 try
01116 {
01117 youbot::EthercatMaster::getInstance().AutomaticSendOn(false);
01118 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->getArmJoint(1).setData(currentStopMovement);
01119 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->getArmJoint(2).setData(currentStopMovement);
01120 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->getArmJoint(3).setData(currentStopMovement);
01121 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->getArmJoint(4).setData(currentStopMovement);
01122 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->getArmJoint(5).setData(currentStopMovement);
01123 youbot::EthercatMaster::getInstance().AutomaticSendOn(true);
01124 }
01125 catch (std::exception& e)
01126 {
01127 std::string errorMessage = e.what();
01128 ROS_WARN("Cannot switch off the arm motors: %s", errorMessage.c_str());
01129 return false;
01130 }
01131 }
01132 else
01133 {
01134 ROS_ERROR("Arm%i not initialized!", armIndex + 1);
01135 return false;
01136 }
01137 areArmMotorsSwitchedOn = false;
01138 return true;
01139 }
01140
01141 bool YouBotOODLWrapper::switchOnArmMotorsCallback(std_srvs::Empty::Request& request,
01142 std_srvs::Empty::Response& response, int armIndex)
01143 {
01144 ROS_INFO("Switch on the arm%i motors", armIndex + 1);
01145 ROS_ASSERT(0 <= armIndex && armIndex < static_cast<int>(youBotConfiguration.youBotArmConfigurations.size()));
01146
01147 if (youBotConfiguration.hasArms && youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm != 0)
01148 {
01149 try
01150 {
01151 std::vector < youbot::JointSensedAngle > sensedJointAngleVector;
01152 std::vector < youbot::JointAngleSetpoint > desiredJointAngleVector;
01153 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->getJointData(sensedJointAngleVector);
01154 youbot::JointAngleSetpoint desiredJointAngle;
01155 for (unsigned int i = 0; i < sensedJointAngleVector.size(); i++)
01156 {
01157 desiredJointAngle = sensedJointAngleVector[i].angle;
01158 desiredJointAngleVector.push_back(desiredJointAngle);
01159 }
01160 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->setJointData(desiredJointAngleVector);
01161 }
01162 catch (std::exception& e)
01163 {
01164 std::string errorMessage = e.what();
01165 ROS_WARN("Cannot switch on the arm motors: %s", errorMessage.c_str());
01166 return false;
01167 }
01168 }
01169 else
01170 {
01171 ROS_ERROR("Arm%i not initialized!", armIndex + 1);
01172 return false;
01173 }
01174 areArmMotorsSwitchedOn = true;
01175 return true;
01176 }
01177
01178 bool YouBotOODLWrapper::calibrateArmCallback(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response,
01179 int armIndex)
01180 {
01181 ROS_INFO("Calibrate the arm%i", armIndex + 1);
01182 ROS_ASSERT(0 <= armIndex && armIndex < static_cast<int>(youBotConfiguration.youBotArmConfigurations.size()));
01183
01184 if (youBotConfiguration.hasArms && youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm != 0)
01185 {
01186
01187 try
01188 {
01189 youBotConfiguration.youBotArmConfigurations[armIndex].youBotArm->calibrateManipulator(true);
01190 }
01191 catch (std::exception& e)
01192 {
01193 std::string errorMessage = e.what();
01194 ROS_WARN("Cannot calibrate the arm: %s", errorMessage.c_str());
01195 return false;
01196 }
01197 }
01198 else
01199 {
01200 ROS_ERROR("Arm%i not initialized!", armIndex + 1);
01201 return false;
01202 }
01203 return true;
01204 }
01205
01206 bool YouBotOODLWrapper::reconnectCallback(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response)
01207 {
01208
01209 this->stop();
01210
01211
01212 bool youBotHasBase;
01213 bool youBotHasArms;
01214 node.param("youBotHasBase", youBotHasBase, false);
01215 node.param("youBotHasArms", youBotHasArms, false);
01216 std::vector<std::string> armNames;
01217
01218
01219 int i = 1;
01220 std::stringstream armNameParam;
01221 armNameParam << "youBotArmName" << i;
01222 while (node.hasParam(armNameParam.str()))
01223 {
01224 std::string armName;
01225 node.getParam(armNameParam.str(), armName);
01226 armNames.push_back(armName);
01227 armNameParam.str("");
01228 armNameParam << "youBotArmName" << (++i);
01229 }
01230
01231 ROS_ASSERT((youBotHasBase == true) || (youBotHasArms == true));
01232 if (youBotHasBase == true)
01233 {
01234 this->initializeBase(this->youBotConfiguration.baseConfiguration.baseID);
01235 }
01236
01237 if (youBotHasArms == true)
01238 {
01239 std::vector<std::string>::iterator armNameIter;
01240 for (armNameIter = armNames.begin(); armNameIter != armNames.end(); ++armNameIter)
01241 {
01242 this->initializeArm(*armNameIter);
01243 }
01244 }
01245 return true;
01246 }
01247
01248 void YouBotOODLWrapper::publishArmAndBaseDiagnostics(double publish_rate_in_secs)
01249 {
01250
01251 if ((ros::Time::now() - lastDiagnosticPublishTime).toSec() < publish_rate_in_secs)
01252 return;
01253
01254 lastDiagnosticPublishTime = ros::Time::now();
01255
01256 diagnosticArrayMessage.header.stamp = ros::Time::now();
01257 diagnosticArrayMessage.status.clear();
01258
01259
01260 diagnosticStatusMessage.name = "platform_Base";
01261 if (youBotConfiguration.hasBase)
01262 {
01263 diagnosticStatusMessage.message = "base is present";
01264 diagnosticStatusMessage.level = diagnostic_msgs::DiagnosticStatus::OK;
01265 }
01266 else
01267 {
01268 diagnosticStatusMessage.message = "base is not connected or switched off";
01269 diagnosticStatusMessage.level = diagnostic_msgs::DiagnosticStatus::ERROR;
01270 }
01271
01272 diagnosticArrayMessage.status.push_back(diagnosticStatusMessage);
01273
01274 diagnosticStatusMessage.name = "platform_Arm";
01275 if (youBotConfiguration.hasArms)
01276 {
01277 diagnosticStatusMessage.message = "arm is present";
01278 diagnosticStatusMessage.level = diagnostic_msgs::DiagnosticStatus::OK;
01279 }
01280 else
01281 {
01282 diagnosticStatusMessage.message = "arm is not connected or switched off";
01283 diagnosticStatusMessage.level = diagnostic_msgs::DiagnosticStatus::ERROR;
01284 }
01285
01286 diagnosticArrayMessage.status.push_back(diagnosticStatusMessage);
01287
01288
01289 platformStateMessage.header.stamp = ros::Time::now();
01290
01291 if (youBotConfiguration.hasBase && areBaseMotorsSwitchedOn)
01292 platformStateMessage.circuit_state[0] = youbot_oodl::PowerBoardState::STATE_ENABLED;
01293 else if (youBotConfiguration.hasBase && !areBaseMotorsSwitchedOn)
01294 platformStateMessage.circuit_state[0] = youbot_oodl::PowerBoardState::STATE_STANDBY;
01295 else
01296 platformStateMessage.circuit_state[0] = youbot_oodl::PowerBoardState::STATE_DISABLED;
01297
01298 if (youBotConfiguration.hasArms && areArmMotorsSwitchedOn)
01299 platformStateMessage.circuit_state[1] = youbot_oodl::PowerBoardState::STATE_ENABLED;
01300 else if (youBotConfiguration.hasArms && !areArmMotorsSwitchedOn)
01301 platformStateMessage.circuit_state[1] = youbot_oodl::PowerBoardState::STATE_STANDBY;
01302 else
01303 platformStateMessage.circuit_state[1] = youbot_oodl::PowerBoardState::STATE_DISABLED;
01304
01305
01306 dashboardMessagePublisher.publish(platformStateMessage);
01307 diagnosticArrayPublisher.publish(diagnosticArrayMessage);
01308 }
01309
01310 }
01311
01312