PSL_2021 / Mbed OS prog_robot_Eve_v1

Dependencies:   mbed-os nRF24L01P

Committer:
evedelegue
Date:
Fri Feb 25 10:13:06 2022 +0000
Revision:
9:67d737d8a349
Child:
11:5f2289e0d0e8
premiere version juste pour la com (mais %f bug)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
evedelegue 9:67d737d8a349 1 /**
evedelegue 9:67d737d8a349 2 * @file MX12.ccp
evedelegue 9:67d737d8a349 3 * @brief This file contains all the methods of the MX12 class
evedelegue 9:67d737d8a349 4 * whose prototypes are in the MX12.h header file
evedelegue 9:67d737d8a349 5 */
evedelegue 9:67d737d8a349 6
evedelegue 9:67d737d8a349 7 #include "MX12.h"
evedelegue 9:67d737d8a349 8 #include "math.h"
evedelegue 9:67d737d8a349 9
evedelegue 9:67d737d8a349 10 MX12::MX12(PinName tx, PinName rx, int baud)
evedelegue 9:67d737d8a349 11 : _mx12(tx, rx) // initializes UnbufferedSerial object
evedelegue 9:67d737d8a349 12 {
evedelegue 9:67d737d8a349 13 /* Serial bus setup
evedelegue 9:67d737d8a349 14 */
evedelegue 9:67d737d8a349 15 // // Set desired properties (baud-8-N-1)
evedelegue 9:67d737d8a349 16 _mx12.baud(baud); /* modulation speed */
evedelegue 9:67d737d8a349 17 _mx12.format(
evedelegue 9:67d737d8a349 18 8, /* bits */
evedelegue 9:67d737d8a349 19 SerialBase::None, /* parity */
evedelegue 9:67d737d8a349 20 1 /* stop bit */
evedelegue 9:67d737d8a349 21 );
evedelegue 9:67d737d8a349 22 // Register a callback to process a Rx (receive) interrupt.
evedelegue 9:67d737d8a349 23 _mx12.attach(callback(this, &MX12::_Rx_interrupt), SerialBase::RxIrq);
evedelegue 9:67d737d8a349 24
evedelegue 9:67d737d8a349 25 // variable used for message reception
evedelegue 9:67d737d8a349 26 _status_pck = {.raw = "",
evedelegue 9:67d737d8a349 27 .n_byte = 0,
evedelegue 9:67d737d8a349 28 .servo_id = 0,
evedelegue 9:67d737d8a349 29 .length = 0,
evedelegue 9:67d737d8a349 30 .error = 0,
evedelegue 9:67d737d8a349 31 .n_param = 0,
evedelegue 9:67d737d8a349 32 .param = "",
evedelegue 9:67d737d8a349 33 .received_checksum = 0,
evedelegue 9:67d737d8a349 34 .calculated_checksum = 0,
evedelegue 9:67d737d8a349 35 .parsed = false,
evedelegue 9:67d737d8a349 36 .valid = false
evedelegue 9:67d737d8a349 37 };
evedelegue 9:67d737d8a349 38
evedelegue 9:67d737d8a349 39 _parser_state = {.expected_field = PacketField::Header1,
evedelegue 9:67d737d8a349 40 .byte_index = 0,
evedelegue 9:67d737d8a349 41 .param_index = 0
evedelegue 9:67d737d8a349 42 };
evedelegue 9:67d737d8a349 43
evedelegue 9:67d737d8a349 44 // Internal defaults states
evedelegue 9:67d737d8a349 45 _bus_state = SerialState::Idle;
evedelegue 9:67d737d8a349 46
evedelegue 9:67d737d8a349 47 }
evedelegue 9:67d737d8a349 48
evedelegue 9:67d737d8a349 49 void MX12::SetSpeed(unsigned char mot_id, float speed)
evedelegue 9:67d737d8a349 50 {
evedelegue 9:67d737d8a349 51 char data[2];
evedelegue 9:67d737d8a349 52
evedelegue 9:67d737d8a349 53 // Speed absolute value
evedelegue 9:67d737d8a349 54 int goal = (0x3ff * abs(speed));
evedelegue 9:67d737d8a349 55
evedelegue 9:67d737d8a349 56 // Spin direction (CW is negative)
evedelegue 9:67d737d8a349 57 if (speed < 0) {
evedelegue 9:67d737d8a349 58 goal |= (0x1 << 10);
evedelegue 9:67d737d8a349 59 }
evedelegue 9:67d737d8a349 60
evedelegue 9:67d737d8a349 61 data[0] = goal & 0xff;
evedelegue 9:67d737d8a349 62 data[1] = goal >> 8;
evedelegue 9:67d737d8a349 63
evedelegue 9:67d737d8a349 64 // Send instruction
evedelegue 9:67d737d8a349 65 _bus_state = SerialState::Writing;
evedelegue 9:67d737d8a349 66 rw(mot_id, CONTROL_TABLE_MOVING_SPEED, 2, data);
evedelegue 9:67d737d8a349 67 }
evedelegue 9:67d737d8a349 68
evedelegue 9:67d737d8a349 69 void MX12::SetSpeed_rad_s(unsigned char mot_id, float speed)
evedelegue 9:67d737d8a349 70 {
evedelegue 9:67d737d8a349 71 if (speed > MX12_ABSOLUTE_MAX_SPEED_RAD_S) {
evedelegue 9:67d737d8a349 72 SetSpeed(mot_id, 1);
evedelegue 9:67d737d8a349 73 } else if (speed < -MX12_ABSOLUTE_MAX_SPEED_RAD_S) {
evedelegue 9:67d737d8a349 74 SetSpeed(mot_id, -1);
evedelegue 9:67d737d8a349 75 } else {
evedelegue 9:67d737d8a349 76 SetSpeed(mot_id, speed / MX12_ABSOLUTE_MAX_SPEED_RAD_S);
evedelegue 9:67d737d8a349 77 }
evedelegue 9:67d737d8a349 78 }
evedelegue 9:67d737d8a349 79
evedelegue 9:67d737d8a349 80 char MX12::IsAvailable(void)
evedelegue 9:67d737d8a349 81 {
evedelegue 9:67d737d8a349 82 return (_bus_state == SerialState::Idle);
evedelegue 9:67d737d8a349 83 }
evedelegue 9:67d737d8a349 84
evedelegue 9:67d737d8a349 85 void MX12::rw(unsigned char mot_id, char address, char len, char *data)
evedelegue 9:67d737d8a349 86 {
evedelegue 9:67d737d8a349 87
evedelegue 9:67d737d8a349 88 /* Set variables for reception from servovotor */
evedelegue 9:67d737d8a349 89 _answer = 0;
evedelegue 9:67d737d8a349 90 _status_pck = {.raw = "",
evedelegue 9:67d737d8a349 91 .n_byte = 0,
evedelegue 9:67d737d8a349 92 .servo_id = 0,
evedelegue 9:67d737d8a349 93 .length = 0,
evedelegue 9:67d737d8a349 94 .error = 0,
evedelegue 9:67d737d8a349 95 .n_param = 0,
evedelegue 9:67d737d8a349 96 .param = "",
evedelegue 9:67d737d8a349 97 .received_checksum = 0,
evedelegue 9:67d737d8a349 98 .calculated_checksum = 0,
evedelegue 9:67d737d8a349 99 .parsed = false,
evedelegue 9:67d737d8a349 100 .valid = false
evedelegue 9:67d737d8a349 101 };
evedelegue 9:67d737d8a349 102 _parser_state = {.expected_field = PacketField::Header1,
evedelegue 9:67d737d8a349 103 .byte_index = 0,
evedelegue 9:67d737d8a349 104 .param_index = 0
evedelegue 9:67d737d8a349 105 };
evedelegue 9:67d737d8a349 106
evedelegue 9:67d737d8a349 107
evedelegue 9:67d737d8a349 108 /* Initialise instruction packet to forge.
evedelegue 9:67d737d8a349 109 * Instruction Packet is the command data sent to the servomotor.
evedelegue 9:67d737d8a349 110 *
evedelegue 9:67d737d8a349 111 * |Header1|Header2|Packet ID|Length|Instruction|Param1...ParamN|Checksum|
evedelegue 9:67d737d8a349 112 * |-------|-------|---------|------|-----------|---------------|--------|
evedelegue 9:67d737d8a349 113 * | 0xFF | 0xFF |Packet ID|Length|Instruction|Param1...ParamN| CHKSUM |
evedelegue 9:67d737d8a349 114 * | cmd[0]| cmd[1]| cmd[2] |cmd[3]| cmd[4] |cmd[5]... | |
evedelegue 9:67d737d8a349 115 * \__ ___/ \_ _/ \__ __/
evedelegue 9:67d737d8a349 116 * \/ | \/ \/ |
evedelegue 9:67d737d8a349 117 * mot_id | address data |
evedelegue 9:67d737d8a349 118 * | (len = N-1) |
evedelegue 9:67d737d8a349 119 * \__________________ ________________/
evedelegue 9:67d737d8a349 120 * \/
evedelegue 9:67d737d8a349 121 * Length ( cmd[3] )
evedelegue 9:67d737d8a349 122 */
evedelegue 9:67d737d8a349 123 char packet[16];
evedelegue 9:67d737d8a349 124 unsigned char packet_length;
evedelegue 9:67d737d8a349 125
evedelegue 9:67d737d8a349 126 /* Initialise checksum to calculate
evedelegue 9:67d737d8a349 127 * It is used to check if packet is damaged during communication.
evedelegue 9:67d737d8a349 128 * Status Checksum is calculated according to the following formula:
evedelegue 9:67d737d8a349 129 *
evedelegue 9:67d737d8a349 130 * Status Checksum = ~( ID + Length + Error + Parameter1 + … Parameter N )
evedelegue 9:67d737d8a349 131 */
evedelegue 9:67d737d8a349 132 char checksum = 0x00;
evedelegue 9:67d737d8a349 133
evedelegue 9:67d737d8a349 134 /* header 1 = 0xFF (dynamixel protocol 1.0) */
evedelegue 9:67d737d8a349 135 packet[0] = 0xff;
evedelegue 9:67d737d8a349 136
evedelegue 9:67d737d8a349 137 /* header 2 = 0xFF (dynamixel protocol 1.0) */
evedelegue 9:67d737d8a349 138 packet[1] = 0xff;
evedelegue 9:67d737d8a349 139
evedelegue 9:67d737d8a349 140 /* packet ID i.e. servomotor id (dynamixel protocol 1.0) */
evedelegue 9:67d737d8a349 141 packet[2] = mot_id;
evedelegue 9:67d737d8a349 142 checksum += packet[2];
evedelegue 9:67d737d8a349 143
evedelegue 9:67d737d8a349 144 /* Guess instruction type. NULL for read, not NULL for write */
evedelegue 9:67d737d8a349 145 if(data == NULL) { // read instruction
evedelegue 9:67d737d8a349 146 /* byte length of the instruction: parameter and checksum field. */
evedelegue 9:67d737d8a349 147 /* for read instruction: 1 INSTR + */
evedelegue 9:67d737d8a349 148 /* 2 PARAM (starting address, length of data) + 1 CHKSUM */
evedelegue 9:67d737d8a349 149 packet[3] = 4;
evedelegue 9:67d737d8a349 150 checksum += packet[3];
evedelegue 9:67d737d8a349 151
evedelegue 9:67d737d8a349 152 /* set write instruction */
evedelegue 9:67d737d8a349 153 packet[4] = PROTOCOL_INSTRUCTION_READ;
evedelegue 9:67d737d8a349 154 checksum += packet[4];
evedelegue 9:67d737d8a349 155
evedelegue 9:67d737d8a349 156 /* Param 1: address to read in the Control Table of RAM Area */
evedelegue 9:67d737d8a349 157 packet[5] = address;
evedelegue 9:67d737d8a349 158 checksum += packet[5];
evedelegue 9:67d737d8a349 159
evedelegue 9:67d737d8a349 160 /* Param 2: number of bytes to read in the Control Table of RAM Area */
evedelegue 9:67d737d8a349 161 packet[6] = len;
evedelegue 9:67d737d8a349 162 checksum += packet[6];
evedelegue 9:67d737d8a349 163
evedelegue 9:67d737d8a349 164 /* Checksum = ~( ID + Length + Instruction + Param1 + … Param N ) */
evedelegue 9:67d737d8a349 165 packet[7] = ~checksum;
evedelegue 9:67d737d8a349 166
evedelegue 9:67d737d8a349 167 packet_length = 8;
evedelegue 9:67d737d8a349 168 } else { // write instruction
evedelegue 9:67d737d8a349 169 /* byte length of the instruction: parameter and checksum field */
evedelegue 9:67d737d8a349 170 /* For write instruction: 1 INSTR + */
evedelegue 9:67d737d8a349 171 /* (1+len)PARAM (starting Address, bytes to write) + 1 CHKSUM */
evedelegue 9:67d737d8a349 172 packet[3] = 3 + len;
evedelegue 9:67d737d8a349 173 checksum += packet[3];
evedelegue 9:67d737d8a349 174
evedelegue 9:67d737d8a349 175 /* set read instruction */
evedelegue 9:67d737d8a349 176 packet[4] = PROTOCOL_INSTRUCTION_WRITE;
evedelegue 9:67d737d8a349 177 checksum += packet[4];
evedelegue 9:67d737d8a349 178
evedelegue 9:67d737d8a349 179 /* Param 1: address to write in the "Control Table of RAM Area" */
evedelegue 9:67d737d8a349 180 packet[5] = address;
evedelegue 9:67d737d8a349 181 checksum += packet[5];
evedelegue 9:67d737d8a349 182
evedelegue 9:67d737d8a349 183 /* Param 2 to N: data to write in the Control Table of RAM Area */
evedelegue 9:67d737d8a349 184 for(char i = 0; i < len; i++) {
evedelegue 9:67d737d8a349 185 packet[6 + i] = data[i];
evedelegue 9:67d737d8a349 186 checksum += data[i];
evedelegue 9:67d737d8a349 187 }
evedelegue 9:67d737d8a349 188
evedelegue 9:67d737d8a349 189 /* Checksum = ~( ID + Length + Instruction + Param1 + … Param N ) */
evedelegue 9:67d737d8a349 190 packet[6 + len] = ~checksum;
evedelegue 9:67d737d8a349 191
evedelegue 9:67d737d8a349 192 packet_length = 7 + len;
evedelegue 9:67d737d8a349 193 }
evedelegue 9:67d737d8a349 194
evedelegue 9:67d737d8a349 195 // Send packet
evedelegue 9:67d737d8a349 196 if(mot_id != 0xFE) {
evedelegue 9:67d737d8a349 197 for(char i = 0; i < packet_length; i++) {
evedelegue 9:67d737d8a349 198 _mx12.write(&packet[i], 1);
evedelegue 9:67d737d8a349 199 }
evedelegue 9:67d737d8a349 200 }
evedelegue 9:67d737d8a349 201 }
evedelegue 9:67d737d8a349 202
evedelegue 9:67d737d8a349 203 // Debug function to print Serial read
evedelegue 9:67d737d8a349 204 void MX12::PrintSerial()
evedelegue 9:67d737d8a349 205 {
evedelegue 9:67d737d8a349 206 for(int i = 0; i < _status_pck.n_byte; i++) {
evedelegue 9:67d737d8a349 207 printf("%x ", _status_pck.raw[i]);
evedelegue 9:67d737d8a349 208 }
evedelegue 9:67d737d8a349 209 printf("\n");
evedelegue 9:67d737d8a349 210 }
evedelegue 9:67d737d8a349 211
evedelegue 9:67d737d8a349 212 MX12::Status MX12::GetStatus()
evedelegue 9:67d737d8a349 213 {
evedelegue 9:67d737d8a349 214 // Return the corresponding status code
evedelegue 9:67d737d8a349 215 switch(_status_pck.error) {
evedelegue 9:67d737d8a349 216 case 0:
evedelegue 9:67d737d8a349 217 return Ok;
evedelegue 9:67d737d8a349 218 break;
evedelegue 9:67d737d8a349 219 case 1 << 0:
evedelegue 9:67d737d8a349 220 return InputVoltageError;
evedelegue 9:67d737d8a349 221 break;
evedelegue 9:67d737d8a349 222 case 1 << 1:
evedelegue 9:67d737d8a349 223 return AngleLimitError;
evedelegue 9:67d737d8a349 224 break;
evedelegue 9:67d737d8a349 225 case 1 << 2:
evedelegue 9:67d737d8a349 226 return OverheatingError;
evedelegue 9:67d737d8a349 227 break;
evedelegue 9:67d737d8a349 228 case 1 << 3:
evedelegue 9:67d737d8a349 229 return RangeError;
evedelegue 9:67d737d8a349 230 break;
evedelegue 9:67d737d8a349 231 case 1 << 4:
evedelegue 9:67d737d8a349 232 return ChecksumError;
evedelegue 9:67d737d8a349 233 break;
evedelegue 9:67d737d8a349 234 case 1 << 5:
evedelegue 9:67d737d8a349 235 return OverloadError;
evedelegue 9:67d737d8a349 236 break;
evedelegue 9:67d737d8a349 237 case 1 << 6:
evedelegue 9:67d737d8a349 238 return InstructionError;
evedelegue 9:67d737d8a349 239 break;
evedelegue 9:67d737d8a349 240 default:
evedelegue 9:67d737d8a349 241 return Unknown;
evedelegue 9:67d737d8a349 242 }
evedelegue 9:67d737d8a349 243 }
evedelegue 9:67d737d8a349 244
evedelegue 9:67d737d8a349 245 void MX12::_Rx_interrupt()
evedelegue 9:67d737d8a349 246 {
evedelegue 9:67d737d8a349 247
evedelegue 9:67d737d8a349 248 char c;
evedelegue 9:67d737d8a349 249
evedelegue 9:67d737d8a349 250 // Try to read serial
evedelegue 9:67d737d8a349 251 if(_mx12.read(&c, 1)) {
evedelegue 9:67d737d8a349 252
evedelegue 9:67d737d8a349 253 _status_pck.raw[(_parser_state.byte_index)++] = c;
evedelegue 9:67d737d8a349 254
evedelegue 9:67d737d8a349 255 // State-machine parsing
evedelegue 9:67d737d8a349 256 switch(_parser_state.expected_field) {
evedelegue 9:67d737d8a349 257
evedelegue 9:67d737d8a349 258 /* c char is interpreted as a Header1 field */
evedelegue 9:67d737d8a349 259 case PacketField::Header1:
evedelegue 9:67d737d8a349 260
evedelegue 9:67d737d8a349 261 /* do nothing and set next state to Header2 */
evedelegue 9:67d737d8a349 262 _parser_state.expected_field = PacketField::Header2;
evedelegue 9:67d737d8a349 263 break;
evedelegue 9:67d737d8a349 264
evedelegue 9:67d737d8a349 265 /* c char is interpreted as a Header2 field */
evedelegue 9:67d737d8a349 266 case PacketField::Header2:
evedelegue 9:67d737d8a349 267
evedelegue 9:67d737d8a349 268 /* do nothing and set next state to Id */
evedelegue 9:67d737d8a349 269 _parser_state.expected_field = PacketField::Id;
evedelegue 9:67d737d8a349 270 break;
evedelegue 9:67d737d8a349 271
evedelegue 9:67d737d8a349 272 /* c char is interpreted as ID field */
evedelegue 9:67d737d8a349 273 case PacketField::Id:
evedelegue 9:67d737d8a349 274
evedelegue 9:67d737d8a349 275 /* store ID, update checksum and set next state to Length */
evedelegue 9:67d737d8a349 276 _status_pck.servo_id = c;
evedelegue 9:67d737d8a349 277 _status_pck.calculated_checksum += c;
evedelegue 9:67d737d8a349 278 _parser_state.expected_field = PacketField::Length;
evedelegue 9:67d737d8a349 279 break;
evedelegue 9:67d737d8a349 280
evedelegue 9:67d737d8a349 281 /* c char is interpreted as length of message data field
evedelegue 9:67d737d8a349 282 * Length = number of Parameters + 2
evedelegue 9:67d737d8a349 283 * where 2 stands for Length field (1 byte) + Error filed (1 byte)
evedelegue 9:67d737d8a349 284 */
evedelegue 9:67d737d8a349 285 case PacketField::Length:
evedelegue 9:67d737d8a349 286
evedelegue 9:67d737d8a349 287 /* store number of param into _status_pck.n_param,
evedelegue 9:67d737d8a349 288 * update calculated_checksum and set next state to Error
evedelegue 9:67d737d8a349 289 */
evedelegue 9:67d737d8a349 290 _status_pck.n_param = c - 2;
evedelegue 9:67d737d8a349 291 _status_pck.calculated_checksum += c;
evedelegue 9:67d737d8a349 292 _parser_state.expected_field = PacketField::Error;
evedelegue 9:67d737d8a349 293 break;
evedelegue 9:67d737d8a349 294
evedelegue 9:67d737d8a349 295 /* c char is interpreted as error status field */
evedelegue 9:67d737d8a349 296 case PacketField::Error:
evedelegue 9:67d737d8a349 297
evedelegue 9:67d737d8a349 298 /* store error status, update checksum
evedelegue 9:67d737d8a349 299 * and set next state to Data
evedelegue 9:67d737d8a349 300 */
evedelegue 9:67d737d8a349 301 _status_pck.error = c;
evedelegue 9:67d737d8a349 302 _status_pck.calculated_checksum += c;
evedelegue 9:67d737d8a349 303 _parser_state.expected_field = PacketField::Data;
evedelegue 9:67d737d8a349 304 break;
evedelegue 9:67d737d8a349 305
evedelegue 9:67d737d8a349 306 /* c char is interpreted as a param field */
evedelegue 9:67d737d8a349 307 case PacketField::Data:
evedelegue 9:67d737d8a349 308
evedelegue 9:67d737d8a349 309 /* store current param, increase param_index
evedelegue 9:67d737d8a349 310 * and update checksum */
evedelegue 9:67d737d8a349 311 _status_pck.param[(_parser_state.param_index)++] = c;
evedelegue 9:67d737d8a349 312 _status_pck.received_checksum += c;
evedelegue 9:67d737d8a349 313
evedelegue 9:67d737d8a349 314 /* increase param index (_parser_state.dataCount)
evedelegue 9:67d737d8a349 315 * and test if it is the last param to read
evedelegue 9:67d737d8a349 316 */
evedelegue 9:67d737d8a349 317 if(_parser_state.param_index > _status_pck.n_param) {
evedelegue 9:67d737d8a349 318 /* reset param index and set next state to Checksum */
evedelegue 9:67d737d8a349 319 _parser_state.param_index = 0;
evedelegue 9:67d737d8a349 320 _parser_state.expected_field = PacketField::Checksum;
evedelegue 9:67d737d8a349 321 }
evedelegue 9:67d737d8a349 322 break;
evedelegue 9:67d737d8a349 323
evedelegue 9:67d737d8a349 324 /* c char is interpreted as Checksum field */
evedelegue 9:67d737d8a349 325 case PacketField::Checksum:
evedelegue 9:67d737d8a349 326
evedelegue 9:67d737d8a349 327 /* store received_checksum, set parsed, store n_byte,
evedelegue 9:67d737d8a349 328 * evalutate valid and set next state to Header1 */
evedelegue 9:67d737d8a349 329 _status_pck.received_checksum = c;
evedelegue 9:67d737d8a349 330 _status_pck.parsed = true;
evedelegue 9:67d737d8a349 331 _status_pck.n_byte = _parser_state.byte_index;
evedelegue 9:67d737d8a349 332 _status_pck.valid = (_status_pck.received_checksum == c);
evedelegue 9:67d737d8a349 333 _parser_state.expected_field = PacketField::Header1;
evedelegue 9:67d737d8a349 334
evedelegue 9:67d737d8a349 335 /* set seriel state to Idle */
evedelegue 9:67d737d8a349 336 _bus_state = SerialState::Idle;
evedelegue 9:67d737d8a349 337 break;
evedelegue 9:67d737d8a349 338
evedelegue 9:67d737d8a349 339 default:
evedelegue 9:67d737d8a349 340
evedelegue 9:67d737d8a349 341 /* unexpected case. If it occurs it would be due to a
evedelegue 9:67d737d8a349 342 * code error of this class */
evedelegue 9:67d737d8a349 343 break;
evedelegue 9:67d737d8a349 344 }
evedelegue 9:67d737d8a349 345 }
evedelegue 9:67d737d8a349 346 }
evedelegue 9:67d737d8a349 347
evedelegue 9:67d737d8a349 348 /* Code from previous version of the class */
evedelegue 9:67d737d8a349 349
evedelegue 9:67d737d8a349 350 /*
evedelegue 9:67d737d8a349 351 void MX12::ReadPosition(unsigned char mot_id) {
evedelegue 9:67d737d8a349 352 // Make a request, interrupt takes care of everything else
evedelegue 9:67d737d8a349 353 _state = State::ReadingPosition;
evedelegue 9:67d737d8a349 354 rw(mot_id, 0x24, 2, NULL);
evedelegue 9:67d737d8a349 355 }
evedelegue 9:67d737d8a349 356
evedelegue 9:67d737d8a349 357 float MX12::GetPosition(unsigned char mot_id) {
evedelegue 9:67d737d8a349 358 return _angle[mot_id];
evedelegue 9:67d737d8a349 359 }
evedelegue 9:67d737d8a349 360 */
evedelegue 9:67d737d8a349 361
evedelegue 9:67d737d8a349 362
evedelegue 9:67d737d8a349 363
evedelegue 9:67d737d8a349 364
evedelegue 9:67d737d8a349 365
evedelegue 9:67d737d8a349 366
evedelegue 9:67d737d8a349 367 void MX12::cmd_moteur(float Vavance, float Vlat, float Wz)
evedelegue 9:67d737d8a349 368 {
evedelegue 9:67d737d8a349 369 // mettre en mode wh
evedelegue 9:67d737d8a349 370 char data[2];
evedelegue 9:67d737d8a349 371 data[1] = 0;
evedelegue 9:67d737d8a349 372 data[0] = 0;
evedelegue 9:67d737d8a349 373
evedelegue 9:67d737d8a349 374 float W1;
evedelegue 9:67d737d8a349 375 float W2;
evedelegue 9:67d737d8a349 376 float W3;
evedelegue 9:67d737d8a349 377 float Rc;
evedelegue 9:67d737d8a349 378 float R;
evedelegue 9:67d737d8a349 379 float x1;
evedelegue 9:67d737d8a349 380 float x2;
evedelegue 9:67d737d8a349 381 float x3;
evedelegue 9:67d737d8a349 382 float y1;
evedelegue 9:67d737d8a349 383 float y2;
evedelegue 9:67d737d8a349 384 float y3;
evedelegue 9:67d737d8a349 385 float a1;
evedelegue 9:67d737d8a349 386 float a2;
evedelegue 9:67d737d8a349 387 float a3;
evedelegue 9:67d737d8a349 388 Rc=0.08; // rayon du chassis*10
evedelegue 9:67d737d8a349 389 R=0.019; // rayon de la roue*10
evedelegue 9:67d737d8a349 390 W1=0;
evedelegue 9:67d737d8a349 391 W2=0;
evedelegue 9:67d737d8a349 392 W3=0;
evedelegue 9:67d737d8a349 393 a1 = 4.74 ;
evedelegue 9:67d737d8a349 394 a2 = -5.8;
evedelegue 9:67d737d8a349 395 a3 = 3.68;
evedelegue 9:67d737d8a349 396 x1 = -0.0032;
evedelegue 9:67d737d8a349 397 x2 = 0.0616;
evedelegue 9:67d737d8a349 398 x3 = -0.0645;
evedelegue 9:67d737d8a349 399 y1 = 0.072;
evedelegue 9:67d737d8a349 400 y2 = -0.0356;
evedelegue 9:67d737d8a349 401 y3 = -0.0376;
evedelegue 9:67d737d8a349 402 //Vtm_smax=0.8; //sert pour calculer valeurs -999->999
evedelegue 9:67d737d8a349 403 //Vnm_smax=0.9;
evedelegue 9:67d737d8a349 404 //Wcrd_smax=2.9;
evedelegue 9:67d737d8a349 405 //if (Vtm_s>Vtm_smax)
evedelegue 9:67d737d8a349 406 // {Vtm_s=Vtm_smax;}
evedelegue 9:67d737d8a349 407 //if (Vnm_s>Vnm_smax)
evedelegue 9:67d737d8a349 408 // {Vnm_s=Vnm_smax;}
evedelegue 9:67d737d8a349 409 //if (Wcrd_s>Wcrd_smax)
evedelegue 9:67d737d8a349 410 // {Wcrd_s=Wcrd_smax;}
evedelegue 9:67d737d8a349 411 //if (Wcrd_s<-Wcrd_smax)
evedelegue 9:67d737d8a349 412 // {Wcrd_s=-Wcrd_smax;}
evedelegue 9:67d737d8a349 413
evedelegue 9:67d737d8a349 414 W1=1/R*(-cosf(a1)*Vavance + sinf(a1)*y1*Wz - sinf(a1)*Vlat + cosf(a1)*x1*Wz); //loi de commande moteur 1
evedelegue 9:67d737d8a349 415 W2=1/R*(-cosf(a2)*Vavance + sinf(a2)*y2*Wz - sinf(a2)*Vlat + cosf(a2)*x2*Wz);
evedelegue 9:67d737d8a349 416 W3=1/R*(-cosf(a3)*Vavance + sinf(a3)*y3*Wz - sinf(a3)*Vlat + cosf(a3)*x3*Wz);
evedelegue 9:67d737d8a349 417 printf("%d %d %dn\r",(int)(1000*W1),(int)(1000*W2),(int)(1000*W3));
evedelegue 9:67d737d8a349 418
evedelegue 9:67d737d8a349 419
evedelegue 9:67d737d8a349 420 SetSpeed_rad_s(1,W1); // impose la vitesse au moteur 1
evedelegue 9:67d737d8a349 421 SetSpeed_rad_s(2,W2);
evedelegue 9:67d737d8a349 422 SetSpeed_rad_s(3,W3);
evedelegue 9:67d737d8a349 423
evedelegue 9:67d737d8a349 424
evedelegue 9:67d737d8a349 425
evedelegue 9:67d737d8a349 426 }
evedelegue 9:67d737d8a349 427
evedelegue 9:67d737d8a349 428
evedelegue 9:67d737d8a349 429
evedelegue 9:67d737d8a349 430 void MX12::eteindre_moteurs()
evedelegue 9:67d737d8a349 431 {
evedelegue 9:67d737d8a349 432 char data[1];
evedelegue 9:67d737d8a349 433
evedelegue 9:67d737d8a349 434 data[0] = 0;
evedelegue 9:67d737d8a349 435
evedelegue 9:67d737d8a349 436
evedelegue 9:67d737d8a349 437 // Send instruction
evedelegue 9:67d737d8a349 438 _bus_state = SerialState::Writing;
evedelegue 9:67d737d8a349 439 rw(1, CONTROL_TABLE_TORQUE_ENABLE, 1, data);
evedelegue 9:67d737d8a349 440 _bus_state = SerialState::Writing;
evedelegue 9:67d737d8a349 441 rw(2, CONTROL_TABLE_TORQUE_ENABLE, 1, data);
evedelegue 9:67d737d8a349 442 _bus_state = SerialState::Writing;
evedelegue 9:67d737d8a349 443 rw(3, CONTROL_TABLE_TORQUE_ENABLE, 1, data);
evedelegue 9:67d737d8a349 444 }
evedelegue 9:67d737d8a349 445
evedelegue 9:67d737d8a349 446
evedelegue 9:67d737d8a349 447
evedelegue 9:67d737d8a349 448 void MX12::cmd_moteur_multiturn(float pos1, float pos2, float pos3)
evedelegue 9:67d737d8a349 449 {
evedelegue 9:67d737d8a349 450 // eteindre les moteurs
evedelegue 9:67d737d8a349 451 eteindre_moteurs();
evedelegue 9:67d737d8a349 452 // mettre en mode multiturn
evedelegue 9:67d737d8a349 453 char data[2];
evedelegue 9:67d737d8a349 454 data[1] = 255;
evedelegue 9:67d737d8a349 455 data[0] = 15;
evedelegue 9:67d737d8a349 456 _bus_state = SerialState::Writing;
evedelegue 9:67d737d8a349 457 rw(1, CONTROL_TABLE_CW_ANGLE_LIMIT, 2, data);
evedelegue 9:67d737d8a349 458 rw(2, CONTROL_TABLE_CW_ANGLE_LIMIT, 2, data);
evedelegue 9:67d737d8a349 459 rw(3, CONTROL_TABLE_CW_ANGLE_LIMIT, 2, data);
evedelegue 9:67d737d8a349 460
evedelegue 9:67d737d8a349 461
evedelegue 9:67d737d8a349 462 _bus_state = SerialState::Writing;
evedelegue 9:67d737d8a349 463 rw(1, CONTROL_TABLE_CCW_ANGLE_LIMIT, 2, data);
evedelegue 9:67d737d8a349 464 rw(2, CONTROL_TABLE_CCW_ANGLE_LIMIT, 2, data);
evedelegue 9:67d737d8a349 465 rw(3, CONTROL_TABLE_CCW_ANGLE_LIMIT, 2, data);
evedelegue 9:67d737d8a349 466
evedelegue 9:67d737d8a349 467 //relever la position
evedelegue 9:67d737d8a349 468 int pas1 = pos1-28672/60;
evedelegue 9:67d737d8a349 469 int pas2 = pos2-28672/60;
evedelegue 9:67d737d8a349 470 int pas3 = pos3-28672/60;
evedelegue 9:67d737d8a349 471
evedelegue 9:67d737d8a349 472 for (int i = 0; i < 61; i++) {
evedelegue 9:67d737d8a349 473 int goal_position1 = i * pas1 - 28672;
evedelegue 9:67d737d8a349 474 if (goal_position1 < 0) {
evedelegue 9:67d737d8a349 475 goal_position1 = goal_position1 + 28627 + 36864;
evedelegue 9:67d737d8a349 476 }
evedelegue 9:67d737d8a349 477 char data1[2];
evedelegue 9:67d737d8a349 478 data1[1] = goal_position1%256;
evedelegue 9:67d737d8a349 479 data1[0] = goal_position1/256;
evedelegue 9:67d737d8a349 480
evedelegue 9:67d737d8a349 481 int goal_position2 = i * pas2 - 28672;
evedelegue 9:67d737d8a349 482 if (goal_position2 < 0) {
evedelegue 9:67d737d8a349 483 goal_position2 = goal_position2 + 28627 + 36864;
evedelegue 9:67d737d8a349 484 }
evedelegue 9:67d737d8a349 485 char data2[2];
evedelegue 9:67d737d8a349 486 data2[1] = goal_position2%256;
evedelegue 9:67d737d8a349 487 data2[0] = goal_position2/256;
evedelegue 9:67d737d8a349 488
evedelegue 9:67d737d8a349 489 int goal_position3 = i * pas3 - 28672;
evedelegue 9:67d737d8a349 490 if (goal_position3 < 0) {
evedelegue 9:67d737d8a349 491 goal_position3 = goal_position3 + 28627 + 36864;
evedelegue 9:67d737d8a349 492 }
evedelegue 9:67d737d8a349 493 char data3[2];
evedelegue 9:67d737d8a349 494 data3[1] = goal_position3%256;
evedelegue 9:67d737d8a349 495 data3[0] = goal_position3/256;
evedelegue 9:67d737d8a349 496
evedelegue 9:67d737d8a349 497 rw(1, CONTROL_TABLE_GOAL_POSITION, 2, data1);
evedelegue 9:67d737d8a349 498 thread_sleep_for(60);
evedelegue 9:67d737d8a349 499 rw(2, CONTROL_TABLE_GOAL_POSITION, 2, data2);
evedelegue 9:67d737d8a349 500 thread_sleep_for(60);
evedelegue 9:67d737d8a349 501 rw(3, CONTROL_TABLE_GOAL_POSITION, 2, data3);
evedelegue 9:67d737d8a349 502 thread_sleep_for(60);
evedelegue 9:67d737d8a349 503
evedelegue 9:67d737d8a349 504 thread_sleep_for(1000);
evedelegue 9:67d737d8a349 505 }
evedelegue 9:67d737d8a349 506 }