arm_control.cpp
Go to the documentation of this file.
00001 /*
00002  * arm_control.cpp
00003  * Copyright 2013 University of Massachusetts Lowell
00004  * Author: Jonathan Hasenzahl
00005  */
00006 
00007 #include "arm/arm_control.h"
00008 #include <cstdio>
00009 #include <cmath>
00010 
00014 ArmControl::ArmControl()
00015 {
00016         init();
00017         run();
00018 }
00019 
00027 void ArmControl::init()
00028 {
00029         shutdown_ = false;
00030 
00031         // Initialize subscribers and clients
00032     cartesian_sub_ = n_.subscribe("cartesian_moves", 1000,
00033                                   &ArmControl::cartesianMovesCallback, this);
00034     constant_sub_ = n_.subscribe("constant_moves", 1,
00035                                  &ArmControl::constantMoveCallback, this);
00036     constant_time_sub_ = n_.subscribe("constant_move_times", 1,
00037                                       &ArmControl::constantMoveTimeCallback,
00038                                       this);
00039     time_client_ = n_.serviceClient<time_server::time_srv>("time_service");
00040 
00041     // Initialize the ARM
00042     arm_ = ManusArm::instance();
00043     try
00044     {
00045         arm_->init("can0");
00046     }
00047     catch (ArmException& e)
00048     {
00049         printf("%s\n", e.what());
00050         ROS_FATAL("Arm initialization failed");
00051         return;
00052     }
00053 }
00054 
00063 void ArmControl::run()
00064 {
00065         // Move arm into origin position
00066         for (int i = 0; i < CART_MV_ARR_SZ; i++)
00067         {
00068                 cartesian_move_.positions[i] = ORIGIN_POSITION[i];
00069                 cartesian_move_.speeds[i] = 2;
00070         }
00071         arm_->setMoveComplete(false);
00072         arm_->moveCartesian(cartesian_move_);
00073 
00074         // Main loop
00075         while (ros::ok() && !shutdown_)
00076         {
00077                 ros::spinOnce();
00078         }
00079 
00080         // Move arm into final position only if ROS is still ok
00081         if (ros::ok())
00082         {
00083                 for (int i = 0; i < CART_MV_ARR_SZ; i++)
00084                 {
00085                         cartesian_move_.positions[i] = FINAL_POSITION[1][i];
00086                         cartesian_move_.speeds[i] = 2;
00087                 }
00088                 arm_->setMoveComplete(false);
00089                 arm_->moveCartesian(cartesian_move_);
00090 
00091                 while (!arm_->isMoveComplete())
00092                 {
00093                         //printf("Not Complete\n");
00094                         ros::Duration(0.06).sleep();
00095                 }
00096         }
00097 
00098         printf("Arm control shutdown\n");
00099 }
00100 
00113 void ArmControl::cartesianMovesCallback(const arm::cartesian_moves::ConstPtr&
00114                                         cmd)
00115 {
00116         time_server::time_srv end_check;
00117     end_check.request.target = cmd->end;
00118 
00119     for (unsigned int i = 0; i < cmd->moves.size(); i++)
00120     {
00121         if (time_client_.call(end_check))
00122         {
00123             printf("CAT end time : %f\n", end_check.request.target.toSec());
00124             printf("CA run time  : %f\n", cmd->moves[i].header.stamp.toSec());
00125             printf("Server time  : %f\n", end_check.response.actual.toSec());
00126             printf("Delta        : %f\n", end_check.response.delta.toSec());
00127 
00128             // Check for a current move and stop if necessary
00129             if (!arm_->isMoveComplete()) arm_->setMoveComplete(true);
00130 
00131             if (end_check.response.delta > ros::Duration(-0.2))
00132             {
00133                 for (unsigned int j = 0; j < CART_MV_ARR_SZ; j++)
00134                 {
00135                     cartesian_move_.positions[j] = cmd->moves[i].positions[j];
00136                     cartesian_move_.speeds[j] = cmd->moves[i].speeds[j];
00137                 }
00138                 arm_->setMoveComplete(false);
00139                 arm_->moveCartesian(cartesian_move_);
00140             }
00141             else
00142             {
00143                 ROS_INFO("Out of time, movement sequence over!");
00144                 return;
00145             }
00146         }
00147         else
00148         {
00149             ROS_ERROR("Time server is not responding");
00150             return;
00151         }
00152     }
00153 }
00154 
00168 void ArmControl::constantMoveCallback(const arm::constant_move::ConstPtr& cmd)
00169 {
00170         if (cmd->quit)
00171         {
00172                 shutdown_ = true;
00173         }
00174         else if (cmd->query)
00175     {
00176                 printf("\n%s", arm_->getPrintState().c_str());
00177     }
00178     else
00179     {
00180         for (int i = 0; i < CONST_MV_ARR_SZ; i++)
00181                 constant_move_.states[i] = static_cast<int>(cmd->states[i]);
00182         for (int i = 0; i < SPD_ARR_SZ; i++)
00183                 constant_move_.speeds[i] = static_cast<int>(cmd->speeds[i]);
00184         arm_->moveConstant(constant_move_);
00185     }
00186 }
00187 
00197 void ArmControl::constantMoveTimeCallback(const arm::constant_move_time::ConstPtr &cmd)
00198 {
00199     time_server::time_srv end_check;
00200     end_check.request.target = cmd->end;
00201 
00202     if (time_client_.call(end_check))
00203     {
00204         if (end_check.response.delta > ros::Duration(0))
00205         {
00206             ROS_INFO("Moving...");
00207 
00208             printf("Move start time  : %f\n", cmd->header.stamp.toSec());
00209             printf("Server time      : %f\n", end_check.response.actual.toSec());
00210             printf("Delta            : %f\n", (cmd->header.stamp -
00211                     end_check.response.actual).toSec());
00212             printf("Duration of move : %f\n", end_check.response.delta.toSec());
00213 
00214             for (int i = 0; i < CONST_MV_ARR_SZ; i++)
00215             {
00216                 constant_move_.states[i] = cmd->move.states[i];
00217                 if (i < SPD_ARR_SZ)
00218                         constant_move_.speeds[i] = cmd->move.speeds[i];
00219             }
00220             arm_->moveConstant(constant_move_);
00221 
00222             end_check.response.delta.sleep();
00223 
00224             // Stop
00225             for (int i = 0; i < CONST_MV_ARR_SZ; i++)
00226                                 constant_move_.states[i] = 0;
00227             arm_->moveConstant(constant_move_);
00228         }
00229         else
00230             ROS_ERROR("This movement would have started after its ending time");
00231     }
00232     else
00233         ROS_ERROR("Time server is not responding, movement command skipped");
00234 }
00235 
00239 int main(int argc, char** argv)
00240 {
00241     ros::init(argc, argv, "arm_control");
00242     ArmControl arm_control;
00243     return 0;
00244 }


arm
Author(s): Jonathan Hasenzahl
autogenerated on Sun Jan 5 2014 11:12:32