00001
00040
00041
00042 #include <iostream>
00043 #include <vector>
00044
00045
00046 #include <ros/ros.h>
00047 #include <actionlib/client/simple_action_client.h>
00048 #include <actionlib/client/terminal_state.h>
00049
00050
00051 #include "cob_sdh/sdh.h"
00052 #include "cob_sdh/util.h"
00053 #include "cob_sdh/sdhlibrary_settings.h"
00054 #include "cob_sdh/basisdef.h"
00055 #include "cob_sdh/dsa.h"
00056
00057 #include "cob_sdh/dsaboost.h"
00058 #include "cob_sdh/dbg.h"
00059
00060
00061 #include <cob_msgs/JointCommand.h>
00062 #include <cob_msgs/TactileForce.h>
00063 #include <std_msgs/Float32MultiArray.h>
00064 #include <cob_actions/JointCommandAction.h>
00065 #include <cob_msgs/ContactArea.h>
00066
00067
00068 #include <cob_srvs/Trigger.h>
00069 #include <cob_srvs/demoinfo.h>
00070 #include <cob_srvs/GetFingerXYZ.h>
00071 #include <cob_srvs/Force.h>
00072 #include <cob_srvs/SetOperationMode.h>
00073
00074
00075 USING_NAMESPACE_SDH
00076
00083
00084 char const* __help__ =
00085 "Simple script to do grasping with tactile sensor info feedback:\n"
00086 "The hand will move to a pregrasp pose (open hand). You can then\n"
00087 "reach an object to grasp into the hand. The actual grasping\n"
00088 "is started as soon as a contact is detected. The finger\n"
00089 "joints then try to move inwards until a certain\n"
00090 "force is reached on the corresponding tactile sensors.\n"
00091 "\n"
00092 "- Example usage:\n"
00093 " - Make SDH connected to port 2 = COM3 with tactile sensors:\n"
00094 " connected to port 3 = COM4 grasp:\n"
00095 " > demo-contact-grasping -p 2 --dsaport=3\n"
00096 " \n"
00097 " - Make SDH connected to USB to RS232 converter 0 and with tactile sensors:\n"
00098 " connected to USB to RS232 converter 1 grasp:\n"
00099 " > demo-contact-grasping --sdh_rs_device=/dev/ttyUSB0 --dsa_rs_device=/dev/ttyUSB0\n"
00100 " \n"
00101 " - Get the version info of both the joint controllers and the tactile \n"
00102 " sensor firmware from an SDH connected to:\n"
00103 " - port 2 = COM3 (joint controllers) and \n"
00104 " - port 3 = COM4 (tactile sensor controller) \n"
00105 " > demo-contact-grasping --port=2 --dsaport=3 -v\n";
00106 char const* __author__ = "Dirk Osswald: dirk.osswald@de.schunk.com";
00107 char const* __url__ = "http://www.schunk.com";
00108 char const* __version__ = "$Id: demo-contact-grasping.cpp 5022 2009-12-04 16:05:53Z Osswald2 $";
00109 char const* __copyright__ = "Copyright (c) 2007 SCHUNK GmbH & Co. KG";
00110
00111
00112
00113
00114 char const* usage =
00115 "usage: demo-contact-grasping [options]\n" ;
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 double area2;
00144 double area3;
00145
00146
00147
00148 void AreaCallback(const cob_msgs::ContactAreaConstPtr& msg)
00149 {
00150 area2 = msg->data2;
00151 area3 = msg->data3;
00152
00153 }
00154
00155
00156
00157 std::vector<double> mv_;
00158
00159 void Callback(const std_msgs::Float32MultiArrayConstPtr& msg)
00160 {
00161
00162 for (int i=0; i< (int)(sizeof(msg->data)/sizeof(float));i++)
00163 {
00164 mv_.push_back (msg->data[i]);
00165 }
00166
00167 }
00168
00169
00170 void GotoStartPose(std::vector<double>& fa)
00171 {
00172 printf("\nPreparing for grasping, opening hand (using POSE controller)...\n");
00173
00174 fa.resize(0);
00175 fa.push_back( -1.57 );
00176 fa.push_back( -1.57 );
00177 fa.push_back( 0.7854 );
00178 fa.push_back( -0.7854 );
00179 fa.push_back( 0 );
00180 fa.push_back( 0 );
00181 fa.push_back( 0 );
00182 fa.push_back( 0 );
00183 fa.push_back( 0 );
00184
00185
00186
00187 }
00188
00189
00190 void AxisAnglesToFingerAngles( std::vector<double> aa, std::vector<double>& fa0, std::vector<double>& fa1, std::vector<double>& fa2 )
00191 {
00192 fa0[0] = aa[0];
00193 fa0[1] = aa[1];
00194 fa0[2] = aa[2];
00195
00196 fa1[0] = 0.0;
00197 fa1[1] = aa[3];
00198 fa1[2] = aa[4];
00199
00200 fa2[0] = aa[0];
00201 fa2[1] = aa[5];
00202 fa2[2] = aa[6];
00203 }
00204
00205
00206
00207 int main( int argc, char** argv )
00208 {
00209 SDH_ASSERT_TYPESIZES();
00210
00211
00212
00213
00214 ros::init(argc, argv,"cob_sdh_demo");
00215
00216 ros::NodeHandle nh_;
00217
00218 actionlib::SimpleActionClient<cob_actions::JointCommandAction> ac_("JointCommand",true);
00219
00220 cob_actions::JointCommandGoal goal;
00221
00222 cob_msgs::JointCommand command_;
00223
00224
00225
00226
00227
00228 ros::ServiceClient srvClient_SetAxisTargetAcceleration_ = nh_.serviceClient<cob_srvs::Trigger>("SetAxisTargetAcceleration");
00229 ros::ServiceClient srvClient_DemoInfo_ = nh_.serviceClient<cob_srvs::demoinfo>("DemoInfo");
00230 ros::ServiceClient srvClient_GetFingerXYZ_ = nh_.serviceClient<cob_srvs::GetFingerXYZ>("GetFingerXYZ");
00231 ros::ServiceClient srvClient_Updater_ = nh_.serviceClient<cob_srvs::Trigger>("DSAUpdater");
00232 ros::ServiceClient srvClient_CloseHand_ = nh_.serviceClient<cob_srvs::Trigger>("CloseHand");
00233 ros::ServiceClient srvClient_Init = nh_.serviceClient<cob_srvs::Trigger>("Init");
00234 ros::ServiceClient srvClient_Force_ = nh_.serviceClient<cob_srvs::Force>("Force");
00235 ros::ServiceClient srvClient_SetOperationMode = nh_.serviceClient<cob_srvs::SetOperationMode>("SetOperationMode");
00236 std::vector<std::string> JointNames_;
00237 std::vector<std::string> JointNamesAll_;
00238 std::vector<int> axes_;
00239 std::vector<double> targetAngles_;
00240 int debug_level=0;
00241
00242
00243 std::vector<SDH::cSDH::eAxisState> state_;
00244
00245 double timeout_;
00246
00247
00248
00249 cDBG cdbg( false, "red" );
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 cdbg.SetFlag( debug_level > 0 );
00263
00264
00265
00266
00267 cdbg << "Debug messages of " << argv[0] << " are printed like this.\n";
00268
00269
00270 debug_level-=1;
00271
00272
00273 bool srv_querry = false;
00274 int srv_execute = 1;
00275 std::string srv_errorMessage = "no error";
00276
00277 std::cout << "initiating the hand";
00278
00279 cob_srvs::Trigger srv0;
00280 srv_querry = srvClient_Init.call(srv0);
00281 srv_execute = srv0.response.success;
00282 srv_errorMessage = srv0.response.errorMessage.data.c_str();
00283
00284 try
00285 {
00286
00287
00288 timeout_ = 1.0;
00289
00290
00291
00292
00293
00294
00295
00296
00297 std::vector<double> pose;
00298 pose.resize(9);
00299
00300 GotoStartPose(pose);
00301 std::cerr << "Pose generated " << pose[0] << " " << pose[1] << " " << pose[2] << "\n";
00302 command_.positions.resize(9);
00303 for (int i = 0; i<9; i++ )
00304 {
00305 command_.positions[i] = pose[i];
00306
00307 }
00308 goal.command = command_;
00309 goal.hasvelocity = false;
00310 ac_.sendGoal(goal);
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 #if 0
00324
00325 cIsGraspedByArea is_grasped_obj( &ts );
00326 double expected_area_ratio[6] = { 0.5, 0.5, 0.5, 0.5, 0.5, 0.5 };
00327 for ( int i=0; i+unused_opt_ind<argc; i++ )
00328 {
00329 int rc = sscanf( argv[unused_opt_ind+i], "%lf", &expected_area_ratio[i] );
00330 assert( rc == 1 );
00331 }
00332 is_grasped_obj.SetCondition( expected_area_ratio );
00333
00334 while ( true )
00335 {
00336 for ( int m=0; m < 6; m++ )
00337 {
00338 contact_info = ts.GetContactInfo( m );
00339 printf( " m=%d age=%ldms force=%6.1f x=%6.1f y=%6.1f area=%6.1f\n",
00340 m,
00341 ts.GetAgeOfFrame( (cDSA::sTactileSensorFrame*) &ts.GetFrame() ),
00342 contact_info.force, contact_info.cog_x, contact_info.cog_y, contact_info.area );
00343 }
00344 printf( "=> IsGrasped: %d\n", is_grasped_obj.IsGrasped() );
00345
00346 boost::this_thread::sleep(boost::posix_time::milliseconds(100));
00347 }
00348 #endif
00349
00350
00351
00352
00353
00354
00355
00356
00357 printf("\nPress any tactile sensor on the SDH to start searching for contact...") ; fflush( stdout );
00358 mv_.resize(6);
00359 int is_grasped_no = 0;
00360 float threshold = 10;
00361
00362 ros::Subscriber sub = nh_.subscribe("/tactile_tools/mean_values", 100, Callback);
00363
00364
00365
00366 cDBG cdbg(false,"red");
00367 do
00368 {
00369
00370
00371
00372 is_grasped_no = 0;
00373
00374 for ( int m=0; m <(int) (sizeof(mv_)/sizeof(double)); m++ )
00375 {
00376
00377
00378 if( mv_[m] > threshold)
00379 is_grasped_no += 1;
00380
00381 }
00382
00383 printf(" contact area too small\n");
00384
00385 ros::Subscriber sub = nh_.subscribe("/tactile_tools/mean_values", 100, Callback);
00386 boost::this_thread::sleep(boost::posix_time::milliseconds(200));
00387
00388
00389 } while ( is_grasped_no <2 );
00390
00391
00392
00393
00394
00395
00396
00397
00398 ros::Subscriber sub1 = nh_.subscribe("area_data", 100, AreaCallback);
00399
00400 double desired_start_contact_area = 5.0;
00401 while ( (area2 + area3) > desired_start_contact_area )
00402 {
00403 ros::Subscriber sub1 = nh_.subscribe("area_data", 100, AreaCallback);
00404
00405 boost::this_thread::sleep(boost::posix_time::milliseconds(200));
00406 }
00407
00408
00409 printf(" OK, contact detected: \n") ; fflush( stdout );
00410
00411
00412
00413
00414 double desired_force = 5.0;
00415 double vel_per_force = 2.5;
00416 double loop_time = 0.01;
00417 int loop_time_ms = (int) (loop_time * 1000.0);
00418
00419 bool finished = false;
00420 printf( "Simple force based grasping starts:\n" );
00421 printf( " Joints of the opposing fingers 1 and 3 (axes 1,2,5,6) will move in\n" );
00422 printf( " positive direction (inwards) as long as the contact force measured\n" );
00423 printf( " by the tactile sensor patch of that joint is less than\n" );
00424 printf( " the desired force %f\n", desired_force );
00425 printf( " This will use the velocity with acceleration ramp controller.\n" );
00426 printf( "\n" );
00427 printf( " Press a tactile sensor on the middle finger 2 to stop!\n" );
00428 fflush( stdout );
00429
00430
00431
00432
00433
00434
00435
00436
00437 cob_srvs::Trigger srv1;
00438 srv_querry = srvClient_SetAxisTargetAcceleration_.call(srv1);
00439 srv_execute = srv1.response.success;
00440 srv_errorMessage = srv1.response.errorMessage.data.c_str();
00441
00442
00443
00444
00445
00446
00447 std::vector<double> aaa; aaa.resize(9);
00448 std::vector<double> ata; ata.resize(9);
00449 std::vector<double> atv; atv.resize(9);
00450 std::vector<double> fta0(3);
00451 std::vector<double> fta1(3);
00452 std::vector<double> fta2(3);
00453 std::vector<double> fta[3];
00454 fta[0] = fta0;
00455 fta[1] = fta1;
00456 fta[2] = fta2;
00457
00458 std::vector<double> min_angles ;
00459 std::vector<double> max_angles ;
00460 std::vector<double> max_velocities ;
00461
00462
00463 cob_srvs::demoinfo srv2;
00464
00465 srv_querry = srvClient_DemoInfo_.call(srv2);
00466 srv_execute = srv2.response.success;
00467 srv_errorMessage = srv2.response.errorMessage.data.c_str();
00468
00469 for (int i=0; i<7; i++)
00470 {
00471
00472
00473 min_angles.push_back((srv2.response.MinAngle)[i]);
00474
00475 max_angles.push_back( (srv2.response.MaxAngle)[i]);
00476
00477 max_velocities.push_back ((srv2.response.MaxVelocity)[i]);
00478
00479 atv.push_back ((srv2.response.TargetVelocity)[i]);
00480
00481 }
00482
00483
00484 while (true)
00485 {
00486 int nb_ok = 0;
00487
00488
00489
00490 cDSA::sContactInfo contact_middle_prox; contact_middle_prox.area =srv2.response.Contact_info2_area;
00491 cDSA::sContactInfo contact_middle_dist; contact_middle_dist.area =srv2.response.Contact_info3_area;
00492 if ( contact_middle_prox.area + contact_middle_dist.area > desired_start_contact_area )
00493 {
00494 printf ("\nContact on middle finger detected! Stopping demonstration.\n") ; fflush( stdout );
00495 finished = true;
00496 break;
00497 }
00498
00499
00500
00501
00502
00503
00504
00505 cob_srvs::demoinfo srv2;
00506 srv_querry = srvClient_DemoInfo_.call(srv2);
00507 srv_execute = srv2.response.success;
00508 srv_errorMessage = srv2.response.errorMessage.data.c_str();
00509
00510 for (int i=0; i<7; i++)
00511 {
00512
00513 aaa.push_back ((srv2.response.ActualAngle)[i]);
00514 }
00515
00516
00517 ToRange( aaa, min_angles, max_angles );
00518 ata = aaa;
00519
00520
00521
00522
00523
00524
00525
00526 int ais[] = { 1,2, 5,6 };
00527 int mis[] = { 0,1, 4,5 };
00528
00529 std::vector<double> force; force.resize(4);
00530
00531 cob_srvs::Force srv5;
00532 srv_querry = srvClient_Force_.call(srv5);
00533
00534 for (int i =0; i < (int)(sizeof(srv5.response.force_data)/sizeof(double)); i++)
00535 {
00536 force.push_back ((srv5.response.force_data)[i]) ;
00537 }
00538
00539 srv_execute = srv5.response.success;
00540 srv_errorMessage = srv5.response.errorMessage.data.c_str();
00541
00542
00543 for ( int i=0; i < (int) (sizeof( ais ) / sizeof( int )); i++ )
00544 {
00545 int ai = ais[i];
00546 int mi = mis[i];
00547
00548
00549
00550
00551 if((int)force.size() >= mi)
00552
00553 { cdbg << mi << " force=" << force[mi] << "\n";
00554
00555
00556
00557
00558
00559 atv[ai] = (desired_force - force[mi]) * vel_per_force;
00560
00561
00562
00563
00564 atv[ai] = ToRange( atv[ai], -max_velocities[ai], max_velocities[ai] );
00565
00566 if ( force[mi] < desired_force )
00567 {
00568 cdbg << "closing axis " << ai << " with " << atv[ai] << " deg/s\n";
00569 }
00570 else if ( force[mi] > desired_force )
00571 {
00572 cdbg << "opening axis " << ai << " with " << atv[ai] << " deg/s\n";
00573 }
00574 else
00575 {
00576 cdbg << "axis " << ai << " ok\n";
00577 nb_ok += 1;
00578
00579 }
00580 }
00581 else
00582 cdbg << "mi is greater then force size\n";
00583
00584
00585
00586
00587 ata[ai] += atv[ai] * loop_time;
00588
00589
00590 AxisAnglesToFingerAngles( ata, fta[0], fta[1], fta[2] );
00591
00592
00593 #if 0
00594 (cxy, (c01,d01), (c02,d02), (c12,d12)) = hand.CheckFingerCollisions( fta[0], fta[1], fta[2] );
00595 d_min = min( d01, d02, d12);
00596 if ( (cxy || d_min < 2.0) && force < desired_force )
00597 {
00598
00599 printf( "not moving axis %d further due to internal collision (d_min=%f)\n", ai, d_min );
00600 ata[ai] = aaa[ai];
00601 atv[ai] = 0.0;
00602 }
00603 #else
00604
00605 int fi = ( (ai<=2) ? 0 : 2 );
00606
00607
00608
00609 std::vector<double> xyz;
00610 cob_srvs::GetFingerXYZ srv3;
00611 srv3.request.number = fi;
00612 for (i=0; i<(int)(sizeof(fta[fi])/sizeof(double));i++)
00613 {
00614 srv3.request.value[i] = fta[fi][i];
00615 }
00616
00617 srv_querry = srvClient_GetFingerXYZ_.call(srv3);
00618
00619 for (i=0; i<3;i++)
00620 {
00621
00622 xyz.push_back(srv3.response.data[i]);
00623 }
00624
00625 srv_execute = srv3.response.success;
00626 srv_errorMessage = srv3.response.errorMessage.data.c_str();
00627
00628 switch (fi)
00629 {
00630 case 0:
00631 if ( xyz[0] <= 6.0 )
00632 {
00633
00634 printf( "not moving axis %d further due to quadrant crossing of finger %d xyz= %6.1f,%6.1f,%6.1f\n", ai, fi, xyz[0],xyz[1],xyz[2] );
00635 ata[ai] = aaa[ai];
00636 atv[ai] = 0.0;
00637 }
00638 break;
00639 case 2:
00640 if ( xyz[0] >= -6.0 )
00641 {
00642
00643 printf( "not moving axis %d further due to quadrant crossing of finger %d xyz= %6.1f,%6.1f,%6.1f\n", ai, fi, xyz[0],xyz[1],xyz[2] );
00644 ata[ai] = aaa[ai];
00645 atv[ai] = 0.0;
00646 }
00647 break;
00648 default:
00649 assert( fi == 0 || fi == 2 );
00650 }
00651 #endif
00652
00653
00654
00655 }
00656
00657 cdbg.PDM( "moving with %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f deg/s\n", atv[0], atv[1], atv[2], atv[3], atv[4], atv[5], atv[6] );
00658
00659 cob_srvs::SetOperationMode srv6;
00660 srv6.request.operationMode.data = "velocity";
00661
00662 ROS_INFO("changing operation mode to: %s controll", srv6.request.operationMode.data.c_str());
00663 srv_querry = srvClient_SetOperationMode.call(srv6);
00664 srv_execute = srv6.response.success;
00665 srv_errorMessage = srv6.response.errorMessage.data.c_str();
00666
00667 command_.velocities.resize(9); command_.positions.resize(9);
00668
00669 command_.velocities[3] = atv[0];
00670 command_.velocities[7] = atv[1];
00671 command_.velocities[8] = atv[2];
00672 command_.velocities[1] = atv[3];
00673 command_.velocities[2] = atv[4];
00674 command_.velocities[4] = atv[5];
00675 command_.velocities[5] = atv[6];
00676 command_.velocities[0] = 0;
00677 command_.velocities[6] = 0;
00678
00679
00680
00681 goal.command = command_;
00682 goal.hasvelocity = true;
00683 ac_.sendGoal(goal);
00684
00685 finished = (nb_ok == 6);
00686
00687 fflush( stdout );
00688 boost::this_thread::sleep(boost::posix_time::milliseconds(loop_time_ms));
00689
00690 }
00691 cdbg << "after endless loop\n";
00692
00693
00694
00695
00696
00697
00698 cob_srvs::SetOperationMode srv7;
00699 srv7.request.operationMode.data = "position";
00700
00701 ROS_INFO("changing operation mode to: %s controll", srv7.request.operationMode.data.c_str());
00702 srv_querry = srvClient_SetOperationMode.call(srv7);
00703 srv_execute = srv7.response.success;
00704 srv_errorMessage = srv7.response.errorMessage.data.c_str();
00705
00706 command_.positions.resize(9);
00707 for (int i = 0; i<9; i++ )
00708 {
00709 command_.positions[i] = (double)pose[i];
00710 }
00711 goal.command = command_;
00712 goal.hasvelocity = false;
00713 ac_.sendGoal(goal);
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729 cob_srvs::Trigger srv4;
00730 srv_querry = srvClient_CloseHand_.call(srv4);
00731 srv_execute = srv4.response.success;
00732 srv_errorMessage = srv4.response.errorMessage.data.c_str();
00733
00734
00735
00736
00737 }
00738 catch (cSDHLibraryException* e)
00739 {
00740 std::cerr << "demo-contact-grasping main(): An exception was caught: " << e->what() << "\n";
00741 delete e;
00742 }
00743 }
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757