$search
00001 // Copyright (c) 2012 Fraunhofer Institute 00002 // for Manufacturing Engineering and Automation (IPA) 00003 // See the file license.txt for copying permission. 00004 00005 // This program performs homing (referencing) of a device. 00006 // See the user manual for details: 00007 // https://github.com/ipa-tys/canopen/blob/master/doc/usermanual.pdf?raw=true 00008 00009 #include <utility> 00010 #include "canopen.h" 00011 00012 int main(int argc, char *argv[]) { 00013 00014 if (argc != 6) { 00015 std::cout << "Arguments:" << std::endl 00016 << "(1) device file" << std::endl 00017 << "(2) CAN deviceID" << std::endl 00018 << "(3) sync rate [msec]" << std::endl 00019 << "(4) target velocity [rad/sec]" << std::endl 00020 << "(5) acceleration [rad/sec^2]" << std::endl 00021 << "(enter acceleration '0' to omit acceleration phase)" << std::endl 00022 << "Example 1: ./move_device /dev/pcan32 12 10 0.2 0.05" << std::endl 00023 << "Example 2 (reverse direction): " 00024 << "./move_device /dev/pcan32 12 10 -0.2 -0.05" << std::endl; 00025 return -1; 00026 } 00027 std::cout << "Interrupt motion with Ctrl-C" << std::endl; 00028 std::string deviceFile = std::string(argv[1]); 00029 uint16_t CANid = std::stoi(std::string(argv[2])); 00030 canopen::syncInterval = std::chrono::milliseconds(std::stoi(std::string(argv[3]))); 00031 double targetVel = std::stod(std::string(argv[4])); 00032 double accel = std::stod(std::string(argv[5])); 00033 00034 // configure CANopen device objects and custom incoming and outgoing PDOs: 00035 canopen::devices[ CANid ] = canopen::Device(CANid); 00036 canopen::incomingPDOHandlers[ 0x180 + CANid ] = 00037 [CANid](const TPCANRdMsg m) { canopen::schunkDefaultPDO_incoming( CANid, m ); }; 00038 canopen::sendPos = canopen::schunkDefaultPDOOutgoing; 00039 00040 canopen::init(deviceFile, canopen::syncInterval); 00041 00042 canopen::sendSDO(CANid, canopen::modes_of_operation, 00043 canopen::modes_of_operation_interpolated_position_mode); 00044 canopen::initDeviceManagerThread(canopen::deviceManager); 00045 00046 // rest of the code is for moving the device: 00047 if (accel != 0) { // accel of 0 means "move at target vel immediately" 00048 std::chrono::milliseconds accelerationTime 00049 ( static_cast<int>(round( 1000.0 * targetVel / accel)) ); 00050 double vel = 0; 00051 auto startTime = std::chrono::high_resolution_clock::now(); 00052 auto tic = std::chrono::high_resolution_clock::now(); 00053 00054 // increasing velocity ramp up to target velocity: 00055 std::cout << "Accelerating to target velocity" << std::endl; 00056 while (tic < startTime + accelerationTime) { 00057 tic = std::chrono::high_resolution_clock::now(); 00058 vel = accel * 0.000001 * 00059 std::chrono::duration_cast<std::chrono::microseconds>(tic-startTime).count(); 00060 canopen::devices[ CANid ].setVel(vel); 00061 std::this_thread::sleep_for 00062 (canopen::syncInterval - (std::chrono::high_resolution_clock::now() - tic)); 00063 } 00064 } 00065 00066 // constant velocity when target vel has been reached: 00067 std::cout << "Target velocity reached!" << std::endl; 00068 canopen::devices[ CANid ].setVel(targetVel); 00069 00070 while (true) { 00071 std::this_thread::sleep_for(std::chrono::seconds(1)); 00072 } 00073 }