CAN Protocol Revision as of 11:16, 19 October 2012 by Alexalspach (Talk | contribs)
Contents |
CAN Communication
Baud-Rate
The CAN communication baud-rate is 1Mbps.
Non-Periodic Communication
Messages can be sent to initialize or stop CAN communication.
Periodic Communication
The Allegro Hand control software attempts to communicate with the real or simulated hand at a regular control interval. Every 3 milliseconds the joint torques are calculated and the joint angles are updated.
CAN Frames
Standard CAN Packet
The standard CAN packet used for communication contains 8 bytes.
typedef struct{ unsigned char STD_EXT; unsigned long msg_id; //message identifier unsigned char data_length; // char data[8]; // data array } can_msg;
ID (Message Identifier)
The 4 byte integer CAN message is split into the command ID (26 bits), destination ID (3bits) and source ID (3 bits).
1 | 8 | 16 | 24 | 26 | 27 | 29 | 30 | 32 |
RAM |
at least 2GB | |||||||
HDD |
at least 2GB | |||||||
Graphics |
OpenGL 3.0 H/W Acceleration enabled with at least 64Mb of video RAM | |||||||
OS |
MS Windows® XP, MS Windows® Vista, MS Windows® 7 | |||||||
Additional S/W |
MS Visual Studio® | |||||||
CAN Interface |
NI, Softing, Kvaser or ESD CAN Note: Any CAN interface can be user-configured for use with the Allegro Hand. |
Command Identifiers
TABLE GOES HERE
Source and Destination Identifiers
TABLE GOES HERE
whatever
Case-study: Softing CAN
In this chapter, sample code demonstrating the implementation of the CAN communication interface is provide. This is the foundation for Softing PCI CAN.
Opening the CAN Communication Channel
char ch_name[256]; sprintf_s(ch_name, 256, "CAN-ACx-PCI_%d", ch); INIL2_initialize_channel(&hCAN[ch-1], ch_name); L2CONFIG L2Config; L2Config.fBaudrate = 1000.0; L2Config.bEnableAck = 0; L2Config.bEnableErrorframe = 0; L2Config.s32AccCodeStd = 0; L2Config.s32AccMaskStd = 0; L2Config.s32AccCodeXtd = 0; L2Config.s32AccMaskXtd = 0; L2Config.s32OutputCtrl = GET_FROM_SCIM; L2Config.s32Prescaler = 1; L2Config.s32Sam = 0; L2Config.s32Sjw = 1; L2Config.s32Tseg1 = 4; L2Config.s32Tseg2 = 3; L2Config.hEvent = (void*)-1; CANL2_initialize_fifo_mode(hCAN[ch-1], &L2Config);
CAN Initialization
long Txid; unsigned char data[8]; Txid = ((unsigned long)ID_CMD_SET_PERIOD<<6) | ((unsigned long)ID_COMMON <<3) | ((unsigned long)ID_DEVICE_MAIN); data[0] = (unsigned char)period_msec; canWrite(hCAN, Txid, data, 1, STD); Sleep(10); Txid = ((unsigned long)ID_CMD_SET_MODE_TASK<<6) | ((unsigned long)ID_COMMON <<3) | ((unsigned long)ID_DEVICE_MAIN); canWrite(hCAN, Txid, data, 0, STD); Sleep(10); Txid = ((unsigned long)ID_CMD_QUERY_STATE_DATA<<6) | ((unsigned long)ID_COMMON <<3) | ((unsigned long)ID_DEVICE_MAIN); canWrite(hCAN, Txid, data, 0, STD);
Starting Periodic CAN Communication
When you start periodic CAN communication, joint angles are automatically updated according to the torque control input.
long Txid; unsigned char data[8]; Txid = ((unsigned long)ID_CMD_QUERY_STATE_DATA<<6) | ((unsigned long)ID_COMMON <<3) | ((unsigned long)ID_DEVICE_MAIN); canWrite(hCAN[ch-1], Txid, data, 0, STD); Sleep(10); Txid = ((unsigned long)ID_CMD_SET_SYSTEM_ON<<6) | ((unsigned long)ID_COMMON <<3) | ((unsigned long)ID_DEVICE_MAIN); canWrite(hCAN[ch-1], Txid, data, 0, STD);
Stopping Periodic CAN Communication
long Txid; unsigned char data[8]; Txid = ((unsigned long)ID_CMD_SET_SYSTEM_OFF<<6) | ((unsigned long)ID_COMMON <<3) | ((unsigned long)ID_DEVICE_MAIN); canWrite(hCAN[ch-1], Txid, data, 0, STD);
Transmitting Control Torques
Control inputs for the four joints in each finger should be packed in a single CAN frame. The sample code below demontrates how to encode four PWM inputs into an 8 byte data buffer and how to set the CAN frame ID properly.
long Txid; unsigned char data[8]; float torque2pwm = 800.0f short pwm[4] = { 0.1*torque2pwm, 0.1*torque2pwm, 0.1*torque2pwm, 0.1*torque2pwm }; if (findex >= 0 && findex < 4) { data[0] = (unsigned char)( (pwm[0] >> 8) & 0x00ff); data[1] = (unsigned char)(pwm[0] & 0x00ff); data[2] = (unsigned char)( (pwm[1] >> 8) & 0x00ff); data[3] = (unsigned char)(pwm[1] & 0x00ff); data[4] = (unsigned char)( (pwm[2] >> 8) & 0x00ff); data[5] = (unsigned char)(pwm[2] & 0x00ff); data[6] = (unsigned char)( (pwm[3] >> 8) & 0x00ff); data[7] = (unsigned char)(pwm[3] & 0x00ff); Txid = ((unsigned long)(ID_CMD_SET_TORQUE_1 + findex)<<6) | ((unsigned long)ID_COMMON <<3) | ((unsigned long)ID_DEVICE_MAIN); canWrite(hCAN, Txid, data, 8, STD); }
Receiving Joint Angles
Each finger consists of four joints. The joint angles for those four joints can be received via one CAN packet. The sample code below demonstrates the method for decoding the data buffer and reading the joint angles.
The sample code assumes that when fingers are in their zero positions, the joint angles from the can packet are 32768. In practice, users should perform experiments and introduce offsets to obtain the zero position.
char cmd; char src; char des; int len; unsigned char data[8]; int ret; can_msg msg; PARAM_STRUCT param; ret = CANL2_read_ac(hCAN, ¶m); switch (ret) { case CANL2_RA_DATAFRAME: msg.msg_id = param.Ident; msg.STD_EXT = STD; msg.data_length = param.DataLength; msg.data[0] = param.RCV_data[0]; msg.data[1] = param.RCV_data[1]; msg.data[2] = param.RCV_data[2]; msg.data[3] = param.RCV_data[3]; msg.data[4] = param.RCV_data[4]; msg.data[5] = param.RCV_data[5]; msg.data[6] = param.RCV_data[6]; msg.data[7] = param.RCV_data[7]; break; } cmd = (char)( (msg.msg_id >> 6) & 0x1f ); des = (char)( (msg.msg_id >> 3) & 0x07 ); src = (char)( msg.msg_id & 0x07 ); len = (int)( msg.data_length ); for(int nd=0; nd<len; nd++) data[nd] = msg.data[nd]; switch (cmd) { case ID_CMD_QUERY_CONTROL_DATA: { if (id_src >= ID_DEVICE_SUB_01 && id_src <= ID_DEVICE_SUB_04) { int temp_pos[4]; // raw angle data float ang[4]; // degree float q[4]; // radian temp_pos[0] = (int)(data[0] | (data[1] << 8)); temp_pos[1] = (int)(data[2] | (data[3] << 8)); temp_pos[2] = (int)(data[4] | (data[5] << 8)); temp_pos[3] = (int)(data[6] | (data[7] << 8)); ang[0] = ((float)(temp_pos[0]-32768)*(333.3f/65536.0f))*(1); ang[1] = ((float)(temp_pos[1]-32768)*(333.3f/65536.0f))*(1); ang[2] = ((float)(temp_pos[2]-32768)*(333.3f/65536.0f))*(1); ang[3] = ((float)(temp_pos[3]-32768)*(333.3f/65536.0f))*(1); q[0] = (3.141592f/180.0f) * ang[0]; q[1] = (3.141592f/180.0f) * ang[1]; q[2] = (3.141592f/180.0f) * ang[2]; q[3] = (3.141592f/180.0f) * ang[3]; } } }
Download
File:AllegroHandCanProtocol.pdf ----------- Work in Progress.
File:AllegroHandCanProtocol KR.pdf
Copyright & Trademark Notice
Allegro, the Allegro logo, RoboticsLab, the RoboticsLab logo, and all related files and documentation are Copyright ⓒ 2008-2020 Wonik Robotics Co., Ltd. All rights reserved. RoboticsLab and Allegro are trademarks of Wonik Robotics. All other trademarks or registered trademarks mentioned are the properties of their respective owners.
Wonik Robotics's Allegro Hand is based on licensed technology developed by the Humanoid Robot Hand research group at the Korea Institute of Industrial Technology (KITECH).
Any references to the BHand Library or the Allegro Hand Motion and/or Grasping Library refer to a library of humanoid robotic hand grasping algorithms and motions developed and published by KITECH researchers.
J.-H. Bae, S.-W. Park, D. Kim, M.-H. Baeg, and S.-R. Oh, "A Grasp Strategy with the Geometric Centroid of a Groped Object Shape Derived from Contact Spots," Proc. of the 2012 IEEE Int. Conf. on Robotics and Automation (ICRA2012), pp. 3798-3804
Wiki maintained by Sean Yi <seanyi@wonikrobotics.com>
Whos here now: Members 0 Guests 0 Bots & Crawlers 2 |