dxl-voltage.cpp
Go to the documentation of this file.
00001 /*
00002  * dxl-voltage.cpp - FTDI serial communication version
00003  *
00004  *  Created on: Dec 23, 2010
00005  *      Author: Erik Schuitema
00006  */
00007 
00008 #include <sys/mman.h>
00009 #include <signal.h>
00010 #include <threemxl/platform/hardware/dynamixel/dynamixel/Dynamixel.h>
00011 
00012 #include <stdio.h>
00013 #include <stdlib.h>
00014 #include <string.h>
00015 #include <randomc.h>
00016 
00017 LxSerial serialPort;
00018 
00019 #define MAX_DEVICE_NAME_LEN 20
00020 char devicename[MAX_DEVICE_NAME_LEN];
00021 
00022 int gNumDynamixels      = 0;
00023 int gDxlMinID           = 0;
00024 int gDxlMaxID           = DXL_BROADCAST_ID-1;
00025 //int gDynamixelIDs[gNumDynamixels]     = {100, 101, 102, 103, 104, 105}; // hard-coded IDs; legs only
00026 CDynamixel gDynamixels[MAX_NUM_DYNAMIXELS];
00027 
00028 bool gDxlTaskProcDone=false;
00029 bool gMotorsInitialized=false;
00030 
00031 bool gQuit=false;
00032 
00033 void dxl_init_all_motors()
00034 {
00035         if (!gMotorsInitialized)
00036         {
00037                 printf("Detecting dynamixels in the ID range %d-%d ", gDxlMinID, gDxlMaxID);
00038                 gNumDynamixels=0;
00039                 // Find all dynamixels and configure and init them
00040                 CDxlConfig dxlConfig;
00041                 for (int iID=gDxlMinID; iID<=gDxlMaxID; iID++)
00042                 {
00043                         gDynamixels[gNumDynamixels].setSerialPort(&serialPort);
00044                         gDynamixels[gNumDynamixels].setConfig(dxlConfig.setID(iID));
00045                         if (gDynamixels[gNumDynamixels].init(DXL_PING_TIMEOUT, false) == DXL_SUCCESS)   // false means: do not send (the default) config to motor
00046                         {
00047                                 // Dynamixel with ID = iID responded!
00048                                 gNumDynamixels++;
00049                                 printf("\n * Dynamixel found with ID %d. Setting joint mode.", iID);
00050                                 gDynamixels[gNumDynamixels].setEndlessTurnMode(false);
00051                         }
00052                         else
00053                         {
00054                                 printf(".");
00055                                 fflush(stdout);
00056                         }
00057                 }
00058                 gMotorsInitialized=true;
00059                 printf("\nDetection done. Found %d Dynamixels. %s\n", gNumDynamixels, gNumDynamixels>0?"Now reporting:\n":"Quitting.");
00060         }
00061 }
00062 
00063 void dxl_task_off_proc(void *arg)
00064 {
00065         for (int iDx=0; iDx<gNumDynamixels; iDx++)
00066         {
00067                 gDynamixels[iDx].enableTorque(DXL_OFF);
00068         }
00069 }
00070 
00071 void catch_signal(int sig)
00072 {
00073         printf("Break signal received.\n");
00074         gQuit = true;
00075 }
00076 
00077 int main(int argc, char** argv)
00078 {
00079         if (argc < 5)
00080         {
00081                 printf("Usage: dxl-goto [serial device] [baud rate] [ID] [voltage ratio -1..1] (transition fraction)\n");
00082                 return -1;
00083         }
00084 
00085         // Set serial device name
00086         if (strlen(argv[1]) < MAX_DEVICE_NAME_LEN)
00087                 strcpy(devicename, argv[1]);
00088         else
00089         {
00090                 printf("[ERROR] Device name too long (probably not /dev/ttyUSB0 ..)!\n");
00091                 return -1;
00092         }
00093 
00094         // Open serial port
00095         if (!serialPort.port_open(devicename, LxSerial::RS485_FTDI))
00096         {
00097                 printf("[ERROR] Failed to open serial port!\n");
00098                 return -1;
00099         }
00100 
00101         // Set correct baud rate
00102         int baudrate = atoi(argv[2]);
00103         serialPort.set_speed_int(baudrate);
00104 
00105         int ret=0;
00106 
00107         // Find dynamixel and configure and init
00108         int ID = atoi(argv[3]);
00109         CDxlConfig dxlConfig;
00110         gDynamixels[0].setSerialPort(&serialPort);
00111         gDynamixels[0].setConfig(dxlConfig.setID(ID));
00112         if (gDynamixels[0].init(DXL_PING_TIMEOUT, false) == DXL_SUCCESS)        // false means: do not send (the default) config to motor
00113         {
00114                 // Dynamixel with ID = iID responded!
00115                 gNumDynamixels++;
00116                 printf("\n * Dynamixel found with ID %d. Setting voltage mode.\n", ID);
00117                 gDynamixels[0].setEndlessTurnMode(true);
00118         }
00119         else
00120         {
00121                 printf("\n Dynamixel not found. Quitting.\n");
00122                 fflush(stdout);
00123                 return -1;
00124         }
00125 
00126         // Desired voltage
00127         double voltageRatio = atof(argv[4]);
00128         if ((voltageRatio < -1.0) || (voltageRatio > 1.0))
00129         {
00130                 printf("\n Error: voltage ratio must be between -1.0 and 1.0. Quitting.\n");
00131                 return -1;
00132         }
00133 
00134         // Desired fraction of transition steps (e.g., 0.2 means 20% of the steps are used as intermediate voltages between levels)
00135         double transitionFraction = atof(argv[5]);
00136         if ((transitionFraction < 0.0) || (transitionFraction > 1.0))
00137         {
00138                 printf("\n Error: transition fraction must be between 0.0 and 1.0. Quitting.\n");
00139                 return -1;
00140         }
00141 
00142         printf("\n Press Ctrl-C to terminate\n");
00143         // This job can be canceled using Ctrl-C
00144         signal(SIGTERM, catch_signal);
00145         signal(SIGINT, catch_signal);
00146 
00147         gDynamixels[0].setEndlessTurnTorque(voltageRatio);
00148 
00149         gRanrotB.RandomInit(123);
00150         int stepper=0;
00151         double samplefreq = 300.0;
00152         double actuationfreq = 30.0;
00153         int actuationDivider = floor(samplefreq/actuationfreq + 0.5);
00154         double lastVoltageRatio = 0.0;
00155         int mode=0;     // Mode 0: transition steps, mode 1: normal steps
00156         int numTransitionSteps = floor(transitionFraction*actuationDivider + 0.5);      // Number of intermediate levels between old voltage and new voltage
00157         int numNormalSteps = actuationDivider - numTransitionSteps;
00158         printf("Running at %.2fHz, changing actuation pattern at %.2fHz using %d transition steps (=%.1f%%)\n", samplefreq, samplefreq/actuationDivider, numTransitionSteps, 100.0*(double)numTransitionSteps/actuationDivider);
00159         double newVoltageRatio = 0.0;
00160         while (!gQuit)
00161         {
00162                 if (stepper == (numTransitionSteps+numNormalSteps))
00163                 {
00164                         lastVoltageRatio = newVoltageRatio;
00165                         newVoltageRatio = -fabs(voltageRatio) + 2.0*fabs(voltageRatio)*gRanrotB.Random();
00166                         //printf("New voltage ratio calculated: %.3f\n", newVoltageRatio);
00167                         stepper = 0;
00168                 }
00169 
00170                 double actuationRatio = lastVoltageRatio + (newVoltageRatio - lastVoltageRatio)*(std::min(1.0, (double)(stepper+1)/(numTransitionSteps+1)));
00171                 //printf("Setting voltage ratio to: %.3f\n", actuationRatio);
00172                 // Actuate!
00173                 gDynamixels[0].setEndlessTurnTorque(actuationRatio);
00174 
00175                 usleep(1.0E6/samplefreq);
00176                 stepper++;
00177         }
00178 
00179         // ===== PREMATURE ENDING ====
00180         //printf("Quitting while keeping motor operational...\n"); serialPort.port_close(); return 0;
00181         // ===========================
00182 
00183         //while (!gQuit)
00184                 //pause();
00185 
00186         // Always put the motor in position mode before shutting down to work around the bug with magnetic encoders in Dynamixels
00187         // Turn the torque off first to prevent the motor from trying to reach the *last known* position goal
00188         printf("Putting %d motors back in position mode..\n", gNumDynamixels);
00189         for (int iDxl=0; iDxl<gNumDynamixels; iDxl++)
00190         {
00191                 gDynamixels[iDxl].enableTorque(DXL_OFF);
00192                 gDynamixels[iDxl].setEndlessTurnMode(false);
00193         }
00194 
00195         // Always turn off at the end
00196         dxl_task_off_proc(NULL);
00197 
00198         // Clean up
00199         serialPort.port_close();
00200         printf("End of dxl-all.\n");
00201         return 0;
00202 }


threemxl
Author(s):
autogenerated on Thu Jun 6 2019 21:10:52