teleop_arm_key.cpp
Go to the documentation of this file.
00001 /*
00002  * teleop_arm_key.cpp
00003  * Copyright 2013 University of Massachusetts Lowell
00004  * Author: Jonathan Hasenzahl
00005  */
00006 
00007 #include "arm/teleop_arm_key.h"
00008 #include "arm/movement_definitions.h"
00009 #include <signal.h>
00010 #include <termios.h>
00011 #include <stdio.h>
00012 
00013 int kfd = 0;
00014 struct termios cooked, raw;
00015 
00019 TeleopArmKey::TeleopArmKey()
00020 {
00021     cmd_pub_ = n_.advertise<arm::constant_move>("constant_moves", 1);
00022     cmd_.states.fill(0);
00023     cmd_.speeds.fill(0);
00024     cmd_.query = false;
00025     cmd_.quit = false;
00026     init();
00027 }
00028 
00035 void TeleopArmKey::init()
00036 {
00037     // Wait for a subscriber to "constant_moves" before continuing
00038     ROS_INFO("Waiting for subscriber...");
00039     while (cmd_pub_.getNumSubscribers() < 1 && ros::ok());
00040     keyLoop();
00041 }
00042 
00046 void TeleopArmKey::keyLoop()
00047 {
00048     // Get the console in raw mode
00049     tcgetattr(kfd, &cooked);
00050     memcpy(&raw, &cooked, sizeof(struct termios));
00051     raw.c_lflag &=~ (ICANON | ECHO);
00052     
00053     // Setting a new line, then end of file                         
00054     raw.c_cc[VEOL] = 1;
00055     raw.c_cc[VEOF] = 2;
00056     tcsetattr(kfd, TCSANOW, &raw);
00057 
00058     printf("\nNow reading from the keyboard.\n");
00059     printf("Use the keyboard to move the ARM.\n");
00060     printf("Take care not to exceed its range of motion!\n");
00061     
00062     char input;
00063     bool shutdown = false;
00064     bool new_command = false;
00065 
00066     // Continue only while shutdown flag has not been enabled and there is still
00067     // a subscriber to receive messages
00068     while (!shutdown && cmd_pub_.getNumSubscribers() > 0 && ros::ok())
00069     {
00070         // Get the next event from the keyboard  
00071         if(read(kfd, &input, 1) < 0)
00072         {
00073             perror("read():");
00074             exit(-1);
00075         }
00076       
00077         //printf("Key value: 0x%02X\n", input);
00078         new_command = getCommand(input);
00079       
00080         if (new_command)
00081         {
00082             cmd_pub_.publish(cmd_);
00083 
00084             if (cmd_.query)
00085                 cmd_.query = false;
00086             if (cmd_.quit)
00087                 shutdown = true;
00088 
00089             new_command = false;
00090         }
00091     }
00092 }
00093 
00099 bool TeleopArmKey::getCommand(const char c)
00100 {
00101     bool new_command = true;
00102     switch (c)
00103     {
00104     case KEYCODE_BACKSPACE:
00105         cmd_.states.fill(0);
00106         cmd_.speeds.fill(0);
00107         break;
00108 
00109     // Arm control
00110     case KEYCODE_W:
00111         cmd_.states[X] = cmd_.states[X] == ARM_FORWARD ? STOP :
00112                              ARM_FORWARD;
00113         break;
00114     case KEYCODE_A:
00115         cmd_.states[Y] = cmd_.states[Y] == ARM_LEFT ? STOP : ARM_LEFT;
00116         break;
00117     case KEYCODE_S:
00118         cmd_.states[X] = cmd_.states[X] == ARM_BACKWARD ? STOP :
00119                              ARM_BACKWARD;
00120         break;
00121     case KEYCODE_D:
00122         cmd_.states[Y] = cmd_.states[Y] == ARM_RIGHT ? STOP : ARM_RIGHT;
00123         break;
00124     case KEYCODE_Z:
00125         cmd_.states[Z] = cmd_.states[Z] == ARM_UP ? STOP : ARM_UP;
00126         break;
00127     case KEYCODE_X:
00128         cmd_.states[Z] = cmd_.states[Z] == ARM_DOWN ? STOP : ARM_DOWN;
00129         break;
00130     case KEYCODE_F:
00131         // Fold: not implemented
00132         new_command = false;
00133         break;
00134     case KEYCODE_U:
00135         // Unfold: not implemented
00136         new_command = false;
00137         break;
00138     
00139     // Claw control     
00140     case KEYCODE_NUM_4:
00141         cmd_.states[YAW] = cmd_.states[YAW] == CLAW_YAW_LEFT ? STOP :
00142                                 CLAW_YAW_LEFT;
00143         break;
00144     case KEYCODE_NUM_6:
00145         cmd_.states[YAW] = cmd_.states[YAW] == CLAW_YAW_RIGHT ? STOP :
00146                                 CLAW_YAW_RIGHT;
00147         break;
00148     case KEYCODE_NUM_8:
00149         cmd_.states[PITCH] = cmd_.states[PITCH] == CLAW_PITCH_UP ?
00150                                   STOP : CLAW_PITCH_UP;
00151         break;
00152     case KEYCODE_NUM_2:
00153         cmd_.states[PITCH] = cmd_.states[PITCH] == CLAW_PITCH_DOWN ?
00154                                   STOP : CLAW_PITCH_DOWN;
00155         break;
00156     case KEYCODE_NUM_7:
00157         cmd_.states[ROLL] = cmd_.states[ROLL] == CLAW_ROLL_LEFT ?
00158                                  STOP : CLAW_ROLL_LEFT;
00159         break;
00160     case KEYCODE_NUM_9:
00161         cmd_.states[ROLL] = cmd_.states[ROLL] == CLAW_ROLL_RIGHT ?
00162                                  STOP : CLAW_ROLL_RIGHT;
00163         break;
00164     case KEYCODE_NUM_MINUS:
00165         cmd_.states[GRIP] = cmd_.states[GRIP] == CLAW_GRIP_CLOSE ?
00166                                  STOP : CLAW_GRIP_CLOSE;
00167         break;
00168     case KEYCODE_NUM_PLUS:
00169         cmd_.states[GRIP] = cmd_.states[GRIP] == CLAW_GRIP_OPEN ?
00170                                  STOP : CLAW_GRIP_OPEN;
00171         break;
00172     
00173     // Lift control    
00174     case KEYCODE_UP:
00175         cmd_.states[LIFT] = cmd_.states[LIFT] == LIFT_UP ? STOP :
00176                                  LIFT_UP;
00177         break;
00178     case KEYCODE_DOWN:
00179         cmd_.states[LIFT] = cmd_.states[LIFT] == LIFT_DOWN ? STOP :
00180                                  LIFT_DOWN;
00181         break;
00182        
00183     // Other
00184     case KEYCODE_COMMA:
00185         // Currently affects all speeds at once
00186         if (cmd_.speeds[0] > 0)
00187         {
00188             for (int i = 0; i < SPD_ARR_SZ; i++)
00189                 cmd_.speeds[i]--;
00190         }
00191         else
00192             new_command = false;
00193 
00194         printf("Speed[%d]\n", cmd_.speeds[0]);
00195         break;
00196     case KEYCODE_PERIOD:
00197         // Currently affects all speeds at once
00198         if (cmd_.speeds[0] < 4)
00199         {
00200             for (int i = 0; i < SPD_ARR_SZ; i++)
00201                 cmd_.speeds[i]++;
00202         }
00203         else
00204             new_command = false;
00205 
00206         printf("Speed[%d]\n", cmd_.speeds[0]);
00207         break;
00208     case KEYCODE_TAB:
00209         print();
00210         cmd_.query = true;
00211         break;
00212     case KEYCODE_Q:
00213         cmd_.states.fill(0);
00214         cmd_.quit = true;
00215         break;
00216     default:
00217         new_command = false;
00218         break;
00219     }
00220 
00221     return new_command;
00222 }
00223 
00227 void TeleopArmKey::print()
00228 {
00229     printf("\nX[%d] Y[%d] Z[%d]\n", cmd_.states[1], cmd_.states[2],
00230            cmd_.states[0]);
00231     printf("Yaw[%d] Pitch[%d] Roll[%d] Grip[%d]\n", cmd_.states[3],
00232            cmd_.states[4], cmd_.states[5], cmd_.states[6]);
00233     printf("Lift[%d] Speed[%d]\n", cmd_.states[7], cmd_.speeds[0]);
00234 }
00235 
00239 void quit(int sig)
00240 {
00241     tcsetattr(kfd, TCSANOW, &cooked);
00242     exit(0);
00243 }
00244 
00248 int main(int argc, char** argv)
00249 {
00250     signal(SIGINT, quit);
00251     
00252     ros::init(argc, argv, "teleop_arm_key");
00253     TeleopArmKey teleop_arm_key;
00254     ros::shutdown(); // To allow arm_control node to shutdown
00255     return 0;
00256 }


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