22 DEBUG_OUT(
"Drive " << this->
NodeID <<
" Writing " << position <<
" to 0x607A");
23 *(&CO_OD_RAM.targetMotorPositions.motor1 + ((this->
NodeID - 1))) = position;
28 DEBUG_OUT(
"Drive " <<
NodeID <<
" Writing " << velocity <<
" to 0x60FF");
29 *(&CO_OD_RAM.targetMotorVelocities.motor1 + ((this->
NodeID - 1))) = velocity;
41 int q = *(&CO_OD_RAM.targetMotorPositions.motor1 + ((this->
NodeID - 1)));
47 return (*(&CO_OD_RAM.actualMotorVelocities.motor1 + ((this->NodeID - 1))));
55 return (*(&CO_OD_RAM.actualMotorTorques.motor1 + ((this->NodeID - 1))));
62 *(&CO_OD_RAM.controlWords.motor1 + ((this->
NodeID - 1))) = 0x06;
67 *(&CO_OD_RAM.controlWords.motor1 + ((this->
NodeID - 1))) = 0x0F;
72 *(&CO_OD_RAM.controlWords.motor1 + ((this->
NodeID - 1))) = 0x00;
86 int controlWord = *(&CO_OD_RAM.controlWords.motor1 + ((this->
NodeID - 1)));
87 *(&CO_OD_RAM.controlWords.motor1 + ((this->
NodeID - 1))) = controlWord ^ 0x10;
88 if ((controlWord & 0x10) > 0) {
119 int COB_ID = 0x100 * PDO_Num + 0x80 +
NodeID;
122 std::vector<std::string> CANCommands;
125 std::stringstream sstream;
128 sstream <<
"[1] " << NodeID <<
" write 0x" << std::hex << 0x1800 + PDO_Num - 1 <<
" 1 u32 0x" << std::hex << 0x800000000 + COB_ID;
129 CANCommands.push_back(sstream.str());
130 sstream.str(std::string());
133 sstream <<
"[1] " << NodeID <<
" write 0x" << std::hex << 0x1A00 + PDO_Num - 1 <<
" 0 u8 0";
134 CANCommands.push_back(sstream.str());
135 sstream.str(std::string());
138 sstream <<
"[1] " << NodeID <<
" write 0x" << std::hex << 0x1800 + PDO_Num - 1 <<
" 2 u8 0x" << SyncRate;
139 CANCommands.push_back(sstream.str());
140 sstream.str(std::string());
142 for (
int i = 1; i <= items.size(); i++) {
144 sstream <<
"[1] " << NodeID <<
" write 0x" << std::hex << 0x1A00 + PDO_Num - 1 <<
" " << i <<
" u32 0x" << std::hex << OD_Addresses[items[i - 1]] * 0x10000 + OD_Data_Size[items[i - 1]];
145 CANCommands.push_back(sstream.str());
146 sstream.str(std::string());
150 sstream <<
"[1] " << NodeID <<
" write 0x" << std::hex << 0x1A00 + PDO_Num - 1 <<
" 0 u8 " << items.size();
151 CANCommands.push_back(sstream.str());
152 sstream.str(std::string());
155 sstream <<
"[1] " << NodeID <<
" write 0x" << std::hex << 0x1800 + PDO_Num - 1 <<
" 1 u32 0x" << std::hex << COB_ID;
156 CANCommands.push_back(sstream.str());
157 sstream.str(std::string());
166 int COB_ID = 0x100 * PDO_Num +
NodeID;
169 std::vector<std::string> CANCommands;
173 std::stringstream sstream;
175 sstream <<
"[1] " << NodeID <<
" write 0x" << std::hex << 0x1400 + PDO_Num - 1 <<
" 1 u32 0x" << std::hex << 0x800000000 + COB_ID;
176 CANCommands.push_back(sstream.str());
177 sstream.str(std::string());
180 sstream <<
"[1] " << NodeID <<
" write 0x" << std::hex << 0x1600 + PDO_Num - 1 <<
" 0 u8 0";
181 CANCommands.push_back(sstream.str());
182 sstream.str(std::string());
185 sstream <<
"[1] " << NodeID <<
" write 0x" << std::hex << 0x1400 + PDO_Num - 1 <<
" 2 u8 0x" << UpdateTiming;
186 CANCommands.push_back(sstream.str());
187 sstream.str(std::string());
189 for (
int i = 1; i <= items.size(); i++) {
191 sstream <<
"[1] " << NodeID <<
" write 0x" << std::hex << 0x1600 + PDO_Num - 1 <<
" " << i <<
" u32 0x" << std::hex << OD_Addresses[items[i - 1]] * 0x10000 + OD_Data_Size[items[i - 1]];
192 CANCommands.push_back(sstream.str());
193 sstream.str(std::string());
197 sstream <<
"[1] " << NodeID <<
" write 0x" << std::hex << 0x1600 + PDO_Num - 1 <<
" 0 u8 " << items.size();
198 CANCommands.push_back(sstream.str());
199 sstream.str(std::string());
202 sstream <<
"[1] " << NodeID <<
" write 0x" << std::hex << 0x1400 + PDO_Num - 1 <<
" 1 u32 0x" << std::hex << COB_ID;
203 CANCommands.push_back(sstream.str());
204 sstream.str(std::string());
211 std::vector<std::string> CANCommands;
213 std::stringstream sstream;
215 sstream <<
"[1] " <<
NodeID <<
" start";
216 CANCommands.push_back(sstream.str());
217 sstream.str(std::string());
219 sstream <<
"[1] " << NodeID <<
" write 0x" << std::hex << 0x6060 <<
" 0 i8 1";
220 CANCommands.push_back(sstream.str());
221 sstream.str(std::string());
224 sstream <<
"[1] " << NodeID <<
" write 0x" << std::hex << 0x6081 <<
" 0 i32 " << positionProfile.
profileVelocity;
225 CANCommands.push_back(sstream.str());
226 sstream.str(std::string());
229 sstream <<
"[1] " << NodeID <<
" write 0x" << std::hex << 0x6083 <<
" 0 i32 " << positionProfile.
profileAccelration;
230 CANCommands.push_back(sstream.str());
231 sstream.str(std::string());
234 sstream <<
"[1] " << NodeID <<
" write 0x" << std::hex << 0x6084 <<
" 0 i32 " << positionProfile.
profileDeceleration;
235 CANCommands.push_back(sstream.str());
236 sstream.str(std::string());
242 std::vector<std::string> CANCommands;
244 std::stringstream sstream;
246 sstream <<
"[1] " <<
NodeID <<
" start";
247 CANCommands.push_back(sstream.str());
248 sstream.str(std::string());
250 sstream <<
"[1] " << NodeID <<
" write 0x" << std::hex << 0x6060 <<
" 0 i8 3";
251 CANCommands.push_back(sstream.str());
252 sstream.str(std::string());
255 sstream <<
"[1] " << NodeID <<
" write 0x" << std::hex << 0x6081 <<
" 0 i32 " << velocityProfile.
profileVelocity;
256 CANCommands.push_back(sstream.str());
257 sstream.str(std::string());
260 sstream <<
"[1] " << NodeID <<
" write 0x" << std::hex << 0x6083 <<
" 0 i32 " << velocityProfile.
profileAccelration;
261 CANCommands.push_back(sstream.str());
262 sstream.str(std::string());
265 sstream <<
"[1] " << NodeID <<
" write 0x" << std::hex << 0x6084 <<
" 0 i32 " << velocityProfile.
profileDeceleration;
266 CANCommands.push_back(sstream.str());
267 sstream.str(std::string());
277 int successfulMessages = 1;
278 for (
auto strCommand : messages) {
280 char *SDO_Message = (
char *)(strCommand.c_str());
295 return successfulMessages;
DriveState driveState
State of the drive.
virtual bool setPos(int position)
int getNodeID()
Get returns the CanNode ID.
Defines some macros for debugging output.
virtual DriveState getDriveState()
Get the current state of the drive.
std::vector< std::string > generateVelControlConfigSDO(motorProfile velocityProfile)
Generates the list of commands required to configure Velocity control in CANopen motor drive...
virtual bool enable()
Sets the state of the drive to "enabled".
virtual int updateDriveStatus()
virtual bool disable()
sets the state of the drive to "disabled"
int error
Current error state of the drive.
virtual bool setTorque(int torque)
virtual bool initPDOs()
Initialises a standard set of PDOs for the use of the drive. These are:
int NodeID
The CAN Node ID used to address this particular drive on the CAN bus.
std::vector< std::string > generateTPDOConfigSDO(std::vector< OD_Entry_t > items, int PDO_Num, int SyncRate)
Generates the list of commands required to configure TPDOs on the drives.
virtual bool readyToSwitchOn()
Changes the state of the drive to "ready to switch on".
Drive()
Construct a new Drive object.
struct to hold desired velocity, acceleration and deceleration values for a drives motor controller p...
virtual bool setVel(int velocity)
int sendSDOMessages(std::vector< std::string > messages)
messages Properly formatted SDO Messages
The Drive class is used to interface with a CANOpen motor drive. According to the CiA402 standard...
std::vector< std::string > generateRPDOConfigSDO(std::vector< OD_Entry_t > items, int PDO_Num, int UpdateTiming)
Generates the list of commands required to configure RPDOs on the drives.
virtual bool posControlConfirmSP()
Flips Bit 4 of Control Word (0x6041) - A new set point is only confirmed if the transition is from 0 ...
void cancomm_socketFree(char *command, char *ret)
int statusWord
Current status word of the drive.
std::vector< std::string > generatePosControlConfigSDO(motorProfile positionProfile)
Generates the list of commands required to configure Position control in CANopen motor drive...