Skip to content
This repository was archived by the owner on Dec 1, 2020. It is now read-only.

Commit 2f15f77

Browse files
JorisWeedamartijnvandermarelRoelemansOlavhaasie
committed
Fix/pm 229/rewrite pdo mapping (#192)
* Check in the write method of the SDO if an error is received, if so; a ros fatal message will be initiated. * Fixed clang format. * Fixed clang format. (now really) * fixed indent errors. * fixed clang format. (NOW REALLY) * fixed clang format. ( NOW REALLY (really) ) * Removed the global variable. It was a redundant decleration. * removed new line. * added the rwc cariable to .h file * removed rwc * added type to the rwc. * PDO map is configured using the example given in the IMC manual. Also short docstrings have been added to improve readability. * Added the reactivation of the sync manager, otherswise the slave would send an error. This version of the PDO-mapping is a working but roughly written code. Has to be cleaned before merging. * Updated layout to match the clang8 format. * fixed byteOffset list. This was necessary because the byteOffset of the next object was given to the currently handled object. * Fixed clang8 format * Removed print statement optimized code to a better readable format. * Updated format to match the cpp style guide * Removed the factor group values. These were unused, the denominator and nominator were both 1. * Rewritten the code to a more sustainable and readable structure. Used the cpp style guide to set a certain standard for future refactor/rewriting of code. (this includes all olav his comments made on the PR) * Added the constructor of the IMCObject because an error occurred when it was removed. * Added lint ignores and utility. * fixed format errors * Removed the test for maximum amount. Because it is not possible with the currently defined IMC PDO Objects. * Set the ethercat communication error protocol using the 6007 register. This is necessary to handle an possible ethercat connection loss. * Updated the comments in the PDO map and edited the for loop condition of the unused PDO registers to match the if condition. * Edit naming convention to match google cpp style guide. * Changed the for loop and if condition for disabling the unused PDO registers. * removed compare operator from the if statement and removed redundant variable from function. * Fixed the if condition. This if statement should be entered if one of the values returns 0. Previously it would enter if all the values are correct. * Changed PDO_objects unordered map back to a normal map, otherwise it wont work!!!! Also changed some last format styling * Moved function of combining address to calculate when the object is created. A separate function is redundant because every object needs this variable. * Changed to const reference to avoid copying each pair in the for each loop. Co-authored-by: martijnvandermarel <martijn.vander.marel@hetnet.nl> Co-authored-by: Roelemans <47626418+Roelemans@users.noreply.github.com> Co-authored-by: Olav de Haas <olavh@protonmail.com>
1 parent bb25ac7 commit 2f15f77

File tree

6 files changed

+177
-179
lines changed

6 files changed

+177
-179
lines changed

march_hardware/include/march_hardware/EtherCAT/EthercatSDO.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#ifndef MARCH_HARDWARE_ETHERCAT_ETHERCATSDO_H
33
#define MARCH_HARDWARE_ETHERCAT_ETHERCATSDO_H
44

5-
#include <stdint.h>
5+
#include <cstdint>
66

77
namespace march4cpp
88
{
@@ -11,4 +11,5 @@ int sdo_bit16(int slave, uint32_t index, uint8_t sub, uint16_t value);
1111
int sdo_bit32(int slave, uint32_t index, uint8_t sub, uint32_t value);
1212

1313
} // namespace march4cpp
14+
1415
#endif // MARCH_HARDWARE_ETHERCAT_ETHERCATSDO_H

march_hardware/include/march_hardware/PDOmap.h

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,40 @@
66
#include <utility>
77
#include <vector>
88
#include <map>
9+
#include <unordered_map>
910

1011
#include <ros/ros.h>
1112

1213
#include <march_hardware/EtherCAT/EthercatSDO.h>
1314

1415
namespace march4cpp
1516
{
17+
/** Store IMC data as a struct to prevent data overlap.*/
1618
struct IMCObject
1719
{
18-
int address; // in IMC memory (see IMC manual)
19-
int length; // bits (see IMC manual)
20+
uint16_t address; // in IMC memory (see IMC manual)
21+
uint16_t length; // bits (see IMC manual)
22+
uint32_t combined_address; // combine the address(hex), sub-index(hex) and length(hex)
2023

21-
explicit IMCObject(int _address, int _length)
24+
explicit IMCObject(uint16_t _address, uint16_t _length) : address(_address), length(_length)
2225
{
23-
this->address = _address;
24-
this->length = _length;
25-
}
26+
uint32_t MSword = ((address & 0xFFFF) << 16); // Shift 16 bits left for most significant word
27+
uint32_t LSword = (length & 0xFFFF);
2628

27-
IMCObject()
28-
{
29+
combined_address = (MSword | LSword);
2930
}
31+
32+
IMCObject(){};
3033
};
3134

35+
/** The data direction to which the PDO is specified is restricted to master in slave out and slave out master in.*/
3236
enum class dataDirection
3337
{
3438
miso,
3539
mosi
3640
};
3741

38-
// If a new object is added to this enum, make sure to also add it to PDOmap::initAllObjects()!
42+
/** All the available IMC object names divided over the PDO maps. make sure to also add it to PDOmap constructor.*/
3943
enum class IMCObjectName
4044
{
4145
StatusWord,
@@ -57,24 +61,27 @@ enum class IMCObjectName
5761
class PDOmap
5862
{
5963
public:
60-
// Constructor
61-
PDOmap();
64+
/** Initiate all the entered IMC objects to prepare the PDO.*/
65+
void addObject(IMCObjectName object_name);
66+
67+
std::map<IMCObjectName, int> map(int slave_index, dataDirection direction);
6268

63-
void addObject(IMCObjectName objectname);
64-
std::map<IMCObjectName, int> map(int slaveIndex, dataDirection direction);
69+
static std::unordered_map<IMCObjectName, IMCObject> all_objects;
6570

6671
private:
67-
void initAllObjects();
68-
void sortPDOObjects();
69-
uint32_t combineAddressLength(uint16_t address, uint16_t length);
70-
std::map<IMCObjectName, IMCObject> PDOObjects;
71-
std::map<IMCObjectName, IMCObject> allObjects;
72-
std::vector<std::pair<IMCObjectName, IMCObject>> sortedPDOObjects;
73-
std::map<IMCObjectName, int> byteOffsets;
74-
75-
const int bitsPerReg = 64;
76-
const int nrofRegs = 4;
77-
const int objectSizes[3] = { 8, 16, 32 };
72+
/** Used to sort the objects in the all_objects according to data length.
73+
* @return list of pairs <IMCObjectName, IMCObjects> according from object sizes */
74+
std::vector<std::pair<IMCObjectName, IMCObject>> sortPDOObjects();
75+
76+
/** Configures the PDO in the IMC using the given base register address and sync manager address.
77+
* @return map of the IMC PDO object name in combination with the byte-offset in the PDO register */
78+
std::map<IMCObjectName, int> configurePDO(int slave_index, int base_register, int base_sync_manager);
79+
80+
std::map<IMCObjectName, IMCObject> PDO_objects;
81+
82+
const int bits_per_register = 64; // Maximum amount of bits that can be constructed in one PDO message.
83+
const int nr_of_regs = 4; // Amount of registers available.
84+
const int object_sizes[3] = { 32, 16, 8 }; // Available sizes.
7885
};
7986
} // namespace march4cpp
8087

march_hardware/src/EtherCAT/EthercatSDO.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,36 @@ namespace march4cpp
1818
int sdo_bit8(int slave, uint32_t index, uint8_t sub, uint8_t value)
1919
{
2020
ROS_DEBUG("sdo_bit8: slaveIndex %i, reg 0x%X, subindex %i, value 0x%X", slave, index, sub, value);
21-
return ec_SDOwrite(slave, index, sub, FALSE, 1, &value, EC_TIMEOUTRXM);
21+
int received_working_counter = ec_SDOwrite(slave, index, sub, FALSE, 1, &value, EC_TIMEOUTRXM);
22+
if (received_working_counter == 0)
23+
{
24+
ROS_FATAL("(sdo_bit8) Error occurred when writing, reg 0x%X, sub-index %i, data: 0x%X to slave %i", index, sub,
25+
value, slave);
26+
}
27+
return received_working_counter;
2228
}
2329

2430
int sdo_bit16(int slave, uint32_t index, uint8_t sub, uint16_t value)
2531
{
2632
ROS_DEBUG("sdo_bit16: slaveIndex %i, reg 0x%X, subindex %i, value 0x%X", slave, index, sub, value);
27-
return ec_SDOwrite(slave, index, sub, FALSE, 2, &value, EC_TIMEOUTRXM);
33+
int received_working_counter = ec_SDOwrite(slave, index, sub, FALSE, 2, &value, EC_TIMEOUTRXM);
34+
if (received_working_counter == 0)
35+
{
36+
ROS_FATAL("(sdo_bit16) Error occurred when writing, reg 0x%X, sub-index %i, data: 0x%X to slave %i", index, sub,
37+
value, slave);
38+
}
39+
return received_working_counter;
2840
}
2941

3042
int sdo_bit32(int slave, uint32_t index, uint8_t sub, uint32_t value)
3143
{
3244
ROS_DEBUG("sdo_bit32: slaveIndex %i, reg 0x%X, subindex %i, value 0x%X", slave, index, sub, value);
33-
return ec_SDOwrite(slave, index, sub, FALSE, 4, &value, EC_TIMEOUTRXM);
45+
int received_working_counter = ec_SDOwrite(slave, index, sub, FALSE, 4, &value, EC_TIMEOUTRXM);
46+
if (received_working_counter == 0)
47+
{
48+
ROS_FATAL("(sdo_bit32) Error occurred when writing, reg 0x%X, sub-index %i, data: 0x%X to slave %i", index, sub,
49+
value, slave);
50+
}
51+
return received_working_counter;
3452
}
35-
3653
} // namespace march4cpp

march_hardware/src/IMotionCube.cpp

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -76,41 +76,38 @@ void IMotionCube::validateMosiPDOs()
7676
void IMotionCube::writeInitialSettings(uint8 ecatCycleTime)
7777
{
7878
ROS_DEBUG("IMotionCube::writeInitialSettings");
79-
bool success = true;
80-
// sdo_bit32(slaveIndex, address, subindex, value);
8179

8280
if (this->actuationMode == ActuationMode::unknown)
8381
{
8482
throw std::runtime_error("Cannot write initial settings to IMotionCube as it has actuation mode of unknown");
8583
}
8684

8785
// mode of operation
88-
success &= sdo_bit8(slaveIndex, 0x6060, 0, this->actuationMode.toModeNumber());
89-
90-
// position dimension index
91-
success &= sdo_bit8(slaveIndex, 0x608A, 0, 1);
92-
93-
// position factor -- scaling factor numerator
94-
success &= sdo_bit32(slaveIndex, 0x6093, 1, 1);
95-
// position factor -- scaling factor denominator
96-
success &= sdo_bit32(slaveIndex, 0x6093, 2, 1);
86+
int mode_of_op = sdo_bit8(slaveIndex, 0x6060, 0, this->actuationMode.toModeNumber());
9787

9888
// position limit -- min position
99-
success &= sdo_bit32(slaveIndex, 0x607D, 1, this->encoder.getLowerSoftLimitIU());
89+
int max_pos_lim = sdo_bit32(slaveIndex, 0x607D, 1, this->encoder.getLowerSoftLimitIU());
90+
10091
// position limit -- max position
101-
success &= sdo_bit32(slaveIndex, 0x607D, 2, this->encoder.getUpperSoftLimitIU());
92+
int min_pos_lim = sdo_bit32(slaveIndex, 0x607D, 2, this->encoder.getUpperSoftLimitIU());
10293

10394
// Quick stop option
104-
success &= sdo_bit16(slaveIndex, 0x605A, 0, 6);
95+
int stop_opt = sdo_bit16(slaveIndex, 0x605A, 0, 6);
10596

10697
// Quick stop deceleration
107-
success &= sdo_bit32(slaveIndex, 0x6085, 0, 0x7FFFFFFF);
98+
int stop_decl = sdo_bit32(slaveIndex, 0x6085, 0, 0x7FFFFFFF);
99+
100+
// Abort connection option code
101+
int abort_con = sdo_bit16(slaveIndex, 0x6007, 0, 1);
108102

109103
// set the ethercat rate of encoder in form x*10^y
110-
success &= sdo_bit8(slaveIndex, 0x60C2, 1, ecatCycleTime);
111-
success &= sdo_bit8(slaveIndex, 0x60C2, 2, -3);
104+
int rate_ec_x = sdo_bit8(slaveIndex, 0x60C2, 1, ecatCycleTime);
105+
int rate_ec_y = sdo_bit8(slaveIndex, 0x60C2, 2, -3);
112106

113-
ROS_ASSERT_MSG(success, "Writing initial settings to IMC %d failed", this->slaveIndex);
107+
if (!(mode_of_op && max_pos_lim && min_pos_lim && stop_opt && stop_decl && abort_con && rate_ec_x && rate_ec_y))
108+
{
109+
ROS_ERROR("Failed writing initial settings to IMC of slave %i", slaveIndex);
110+
}
114111
}
115112

116113
void IMotionCube::actuateRad(float targetRad)

0 commit comments

Comments
 (0)