00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00012
00013
00015
00016 #include <iostream>
00017 #include <boost/thread/thread.hpp>
00018 #include <boost/date_time.hpp>
00019 #include <boost/thread/locks.hpp>
00020
00021 #include "ros/ros.h"
00022 #include "ros/service.h"
00023 #include "ros/service_server.h"
00024 #include "sensor_msgs/JointState.h"
00025 #include "std_msgs/String.h"
00026 #include "std_msgs/Float32.h"
00027
00028 #include <stdio.h>
00029 #include <math.h>
00030 #include <algorithm>
00031 #include <iostream>
00032 #include <string>
00033
00034 #include "controlAllegroHand.h"
00035
00036
00037 #define RADIANS_TO_DEGREES(radians) ((radians) * (180.0 / M_PI))
00038 #define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)
00039
00040
00041
00042 #define JOINT_STATE_TOPIC "/allegroHand/joint_states"
00043 #define JOINT_CMD_TOPIC "/allegroHand/joint_cmd"
00044 #define EXT_CMD_TOPIC "/allegroHand/external_cmd"
00045
00046 #define JOINT_DESIRED_TOPIC "/allegroHand/joint_desired_states"
00047 #define JOINT_CURRENT_TOPIC "/allegroHand/joint_current_states"
00048
00049
00050 double desired_position[DOF_JOINTS] = {0.0};
00051 double current_position[DOF_JOINTS] = {0.0};
00052 double previous_position[DOF_JOINTS] = {0.0};
00053 double current_position_filtered[DOF_JOINTS] = {0.0};
00054 double previous_position_filtered[DOF_JOINTS] = {0.0};
00055
00056 double desired_velocity[DOF_JOINTS] = {0.0};
00057 double current_velocity[DOF_JOINTS] = {0.0};
00058 double previous_velocity[DOF_JOINTS] = {0.0};
00059 double current_velocity_filtered[DOF_JOINTS] = {0.0};
00060
00061 double desired_torque[DOF_JOINTS] = {0.0};
00062
00063
00064 double v[DOF_JOINTS] = {0.0};
00065
00066
00067 double k_p[DOF_JOINTS] = { 1200.0, 1200.0, 1200.0, 1200.0,
00068 1200.0, 1200.0, 1200.0, 1200.0,
00069 1200.0, 1200.0, 1200.0, 1200.0,
00070 1200.0, 1200.0, 1200.0, 1200.0 };
00071
00072 double k_d[DOF_JOINTS] = { 140.0, 140.0, 140.0, 140.0,
00073 140.0, 140.0, 140.0, 140.0,
00074 140.0, 140.0, 140.0, 140.0,
00075 140.0, 140.0, 140.0, 140.0 };
00076
00077
00078 double v_max[DOF_JOINTS] = { 10.0, 10.0, 10.0, 10.0,
00079 10.0, 10.0, 10.0, 10.0,
00080 10.0, 10.0, 10.0, 10.0,
00081 10.0, 10.0, 10.0, 10.0 };
00082
00083
00084 double home_pose[DOF_JOINTS] = { 0.0, -10.0, 45.0, 45.0,
00085 0.0, -10.0, 45.0, 45.0,
00086 5.0, -5.0, 50.0, 45.0,
00087 60.0, 25.0, 15.0, 45.0 };
00088
00089
00090 std::string pGainParams[DOF_JOINTS] = { "~gains_velSat/p/j00", "~gains_velSat/p/j01", "~gains_velSat/p/j02", "~gains_velSat/p/j03",
00091 "~gains_velSat/p/j10", "~gains_velSat/p/j11", "~gains_velSat/p/j12", "~gains_velSat/p/j13",
00092 "~gains_velSat/p/j20", "~gains_velSat/p/j21", "~gains_velSat/p/j22", "~gains_velSat/p/j23",
00093 "~gains_velSat/p/j30", "~gains_velSat/p/j31", "~gains_velSat/p/j32", "~gains_velSat/p/j33"};
00094
00095 std::string dGainParams[DOF_JOINTS] = { "~gains_velSat/d/j00", "~gains_velSat/d/j01", "~gains_velSat/d/j02", "~gains_velSat/d/j03",
00096 "~gains_velSat/d/j10", "~gains_velSat/d/j11", "~gains_velSat/d/j12", "~gains_velSat/d/j13",
00097 "~gains_velSat/d/j20", "~gains_velSat/d/j21", "~gains_velSat/d/j22", "~gains_velSat/d/j23",
00098 "~gains_velSat/d/j30", "~gains_velSat/d/j31", "~gains_velSat/d/j32", "~gains_velSat/d/j33"};
00099
00100 std::string vMaxParams[DOF_JOINTS] = { "~gains_velSat/v_max/j00", "~gains_velSat/v_max/j01", "~gains_velSat/v_max/j02", "~gains_velSat/v_max/j03",
00101 "~gains_velSat/v_max/j10", "~gains_velSat/v_max/j11", "~gains_velSat/v_max/j12", "~gains_velSat/v_max/j13",
00102 "~gains_velSat/v_max/j20", "~gains_velSat/v_max/j21", "~gains_velSat/v_max/j22", "~gains_velSat/v_max/j23",
00103 "~gains_velSat/v_max/j30", "~gains_velSat/v_max/j31", "~gains_velSat/v_max/j32", "~gains_velSat/v_max/j33"};
00104
00105 std::string initialPosition[DOF_JOINTS] = { "~initial_position/j00", "~initial_position/j01", "~initial_position/j02", "~initial_position/j03",
00106 "~initial_position/j10", "~initial_position/j11", "~initial_position/j12", "~initial_position/j13",
00107 "~initial_position/j20", "~initial_position/j21", "~initial_position/j22", "~initial_position/j23",
00108 "~initial_position/j30", "~initial_position/j31", "~initial_position/j32", "~initial_position/j33"};
00109
00110
00111 std::string jointNames[DOF_JOINTS] = { "joint_0.0", "joint_1.0", "joint_2.0", "joint_3.0" ,
00112 "joint_4.0", "joint_5.0", "joint_6.0", "joint_7.0" ,
00113 "joint_8.0", "joint_9.0", "joint_10.0", "joint_11.0",
00114 "joint_12.0", "joint_13.0", "joint_14.0", "joint_15.0" };
00115
00116
00117
00118 int frame = 0;
00119
00120
00121 int lEmergencyStop = 0;
00122
00123 boost::mutex *mutex;
00124
00125
00126 ros::Publisher joint_state_pub;
00127 ros::Publisher joint_desired_state_pub;
00128 ros::Publisher joint_current_state_pub;
00129
00130 ros::Subscriber joint_cmd_sub;
00131 ros::Subscriber external_cmd_sub;
00132 sensor_msgs::JointState msgJoint_desired;
00133 sensor_msgs::JointState msgJoint_current;
00134 sensor_msgs::JointState msgJoint;
00135 std::string ext_cmd;
00136
00137
00138 ros::Time tstart;
00139 ros::Time tnow;
00140
00141 double secs;
00142 double dt;
00143
00144
00145 controlAllegroHand *canDevice;
00146
00147
00148
00149
00150
00151
00152
00153
00154 void SetjointCallback(const sensor_msgs::JointState& msg)
00155 {
00156 mutex->lock();
00157 for(int i=0;i<DOF_JOINTS;i++) desired_position[i] = msg.position[i];
00158 mutex->unlock();
00159 }
00160
00161
00162
00163 void extCmdCallback(const std_msgs::String::ConstPtr& msg)
00164 {
00165 ROS_INFO("CTRL: Processing external command");
00166 ext_cmd = msg->data.c_str();
00167
00168
00169 if (ext_cmd.compare("comparisonString") == 0)
00170 {
00171
00172 }
00173 else
00174 {
00175
00176 }
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186 void timerCallback(const ros::TimerEvent& event)
00187 {
00188
00189
00190 tnow = ros::Time::now();
00191 dt = 1e-9*(tnow - tstart).nsec;
00192 tstart = tnow;
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 for(int i=0; i<DOF_JOINTS; i++)
00203 {
00204 previous_position[i] = current_position[i];
00205 previous_position_filtered[i] = current_position_filtered[i];
00206 previous_velocity[i] = current_velocity[i];
00207 }
00208
00209
00210
00211
00212
00213 canDevice->setTorque(desired_torque);
00214 lEmergencyStop = canDevice->update();
00215 canDevice->getJointInfo(current_position);
00216
00217
00218
00219
00220
00221
00222 if( lEmergencyStop < 0 )
00223 {
00224 ROS_ERROR("\n\nAllegro Hand Node is Shutting Down! (Emergency Stop)\n");
00225 ros::shutdown();
00226 }
00227
00228
00229
00230
00231
00232
00233 for(int i=0; i<DOF_JOINTS; i++)
00234 {
00235 current_position_filtered[i] = (0.6*current_position_filtered[i]) + (0.198*previous_position[i]) + (0.198*current_position[i]);
00236 current_velocity[i] = (current_position_filtered[i] - previous_position_filtered[i]) / dt;
00237 current_velocity_filtered[i] = (0.6*current_velocity_filtered[i]) + (0.198*previous_velocity[i]) + (0.198*current_velocity[i]);
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247 for(int i=0; i<DOF_JOINTS; i++)
00248 {
00249 desired_velocity[i] = (k_p[i]/k_d[i])*(desired_position[i] - current_position_filtered[i]);
00250 v[i] = std::min( 1.0, v_max[i]/fabs(desired_velocity[i]) );
00251 }
00252
00253
00254
00255
00256
00257
00258 if(frame>100)
00259 {
00260 for(int i=0; i<DOF_JOINTS; i++)
00261 {
00262 desired_torque[i] = -k_d[i]*( current_velocity_filtered[i] - v[i]*desired_velocity[i] );
00263 desired_torque[i] = desired_torque[i]/800.0;
00264 }
00265 }
00266
00267
00268
00269
00270 msgJoint.header.stamp = tnow;
00271 msgJoint_desired.header.stamp = tnow;
00272 msgJoint_current.header.stamp = tnow;
00273 for(int i=0; i<DOF_JOINTS; i++)
00274 {
00275 msgJoint.position[i] = current_position_filtered[i];
00276 msgJoint.velocity[i] = current_velocity_filtered[i];
00277 msgJoint.effort[i] = desired_torque[i];
00278
00279 msgJoint_desired.position[i] = desired_position[i];
00280 msgJoint_desired.velocity[i] = desired_velocity[i]*v[i];
00281 msgJoint_desired.effort[i] = desired_torque[i];
00282
00283 msgJoint_current.position[i] = current_position_filtered[i];
00284 msgJoint_current.velocity[i] = current_velocity_filtered[i];
00285 msgJoint_current.effort[i] = desired_torque[i];
00286 }
00287
00288
00289
00290
00291
00292
00293 joint_state_pub.publish(msgJoint);
00294 joint_desired_state_pub.publish(msgJoint_desired);
00295 joint_current_state_pub.publish(msgJoint_current);
00296
00297 frame++;
00298
00299
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309 int main(int argc, char** argv)
00310 {
00311
00312 using namespace std;
00313
00314 ros::init(argc, argv, "allegro_hand_core");
00315 ros::Time::init();
00316
00317 ros::NodeHandle nh;
00318
00319
00320
00321 ros::Timer timer = nh.createTimer(ros::Duration(0.003), timerCallback);
00322
00323 mutex = new boost::mutex();
00324
00325
00326 joint_state_pub = nh.advertise<sensor_msgs::JointState>(JOINT_STATE_TOPIC, 3);
00327 joint_desired_state_pub = nh.advertise<sensor_msgs::JointState>(JOINT_DESIRED_TOPIC, 3);
00328 joint_current_state_pub = nh.advertise<sensor_msgs::JointState>(JOINT_CURRENT_TOPIC, 3);
00329
00330 joint_cmd_sub = nh.subscribe(JOINT_CMD_TOPIC, 3, SetjointCallback);
00331 external_cmd_sub = nh.subscribe(EXT_CMD_TOPIC, 1, extCmdCallback);
00332
00333
00334 msgJoint.position.resize(DOF_JOINTS);
00335 msgJoint.velocity.resize(DOF_JOINTS);
00336 msgJoint.effort.resize(DOF_JOINTS);
00337 msgJoint.name.resize(DOF_JOINTS);
00338
00339 msgJoint_desired.position.resize(DOF_JOINTS);
00340 msgJoint_desired.velocity.resize(DOF_JOINTS);
00341 msgJoint_desired.effort.resize(DOF_JOINTS);
00342 msgJoint_desired.name.resize(DOF_JOINTS);
00343
00344 msgJoint_current.position.resize(DOF_JOINTS);
00345 msgJoint_current.velocity.resize(DOF_JOINTS);
00346 msgJoint_current.effort.resize(DOF_JOINTS);
00347 msgJoint_current.name.resize(DOF_JOINTS);
00348
00349
00350
00351 for(int i=0; i<DOF_JOINTS; i++) msgJoint.name[i] = jointNames[i];
00352
00353
00354
00355
00356 string robot_name, whichHand, manufacturer, origin, serial;
00357 double version;
00358 ros::param::get("~hand_info/robot_name",robot_name);
00359 ros::param::get("~hand_info/which_hand",whichHand);
00360 ros::param::get("~hand_info/manufacturer",manufacturer);
00361 ros::param::get("~hand_info/origin",origin);
00362 ros::param::get("~hand_info/serial",serial);
00363 ros::param::get("~hand_info/version",version);
00364
00365
00366
00367 if (ros::param::has("~gains_velSat"))
00368 {
00369 ROS_INFO("CTRL: Velocity Saturation gains loaded from param server.");
00370 for(int i=0; i<DOF_JOINTS; i++)
00371 {
00372 ros::param::get(pGainParams[i], k_p[i]);
00373 ros::param::get(dGainParams[i], k_d[i]);
00374 ros::param::get(vMaxParams[i], v_max[i]);
00375
00376 }
00377
00378 }
00379 else
00380 {
00381
00382 ROS_WARN("CTRL: Velocity Satuartion gains not loaded.\nCheck launch file is loading /parameters/gains_velSat.yaml\nLoading default Vel. Sat. gains...");
00383 }
00384
00385
00386
00387 if (ros::param::has("~initial_position"))
00388 {
00389 ROS_INFO("\n\nCTRL: Initial Pose loaded from param server.\n");
00390 for(int i=0; i<DOF_JOINTS; i++)
00391 {
00392 ros::param::get(initialPosition[i], desired_position[i]);
00393 desired_position[i] = DEGREES_TO_RADIANS(desired_position[i]);
00394 }
00395 }
00396 else
00397 {
00398 ROS_WARN("\n\nCTRL: Initial postion not loaded.\nCheck launch file is loading /parameters/initial_position.yaml\nloading Home position instead...\n");
00399
00400 for(int i=0; i<DOF_JOINTS; i++) desired_position[i] = DEGREES_TO_RADIANS(home_pose[i]);
00401 }
00402
00403
00404
00405 canDevice = new controlAllegroHand();
00406 canDevice->init();
00407 usleep(3000);
00408
00409
00410 cout << endl << endl << robot_name << " v" << version << endl << serial << " (" << whichHand << ")" << endl << manufacturer << endl << origin << endl << endl;
00411
00412
00413 tstart = ros::Time::now();
00414
00415
00416 ros::spin();
00417
00418
00419 nh.shutdown();
00420 delete canDevice;
00421 printf("\nAllegro Hand Node has been shut down. Bye!\n\n");
00422 return 0;
00423
00424 }
00425
00426