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

Feature/pm 524 Generalize motor controller #284

Draft
wants to merge 35 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
6abd775
Create MotorController abstract class
Roelemans Jul 16, 2020
c8f3af5
Merge branch 'develop' into feature/PM-524-add-odrive-option
Roelemans Aug 5, 2020
f07ebf8
Have Joint.cpp use controller instead of imc
Roelemans Aug 6, 2020
1db4b01
Generalise hardware_builder, hardware_interface and ehtercat master a…
Roelemans Aug 7, 2020
7cf1336
Fix tests #1
Roelemans Aug 7, 2020
9d320e5
Fix tests #2
Roelemans Aug 8, 2020
fffab68
Throw a fatal when a joint has no controller defined and remove runti…
Roelemans Aug 8, 2020
ae33d44
Fix error msg
Roelemans Aug 11, 2020
00e9bad
Fix typos
Roelemans Aug 11, 2020
2e1b2f4
Merge branch 'develop' into feature/PM-524-add-odrive-option
Roelemans Aug 11, 2020
ef553b9
Namechange MotorControllerState to MotorControllerStates
Roelemans Aug 11, 2020
a60801f
Fix clang
Roelemans Aug 11, 2020
087227e
Remove tests untill it works
Roelemans Aug 12, 2020
9d8bc65
Fix build
Roelemans Aug 12, 2020
81423e5
Generalise imc_state change some naming and add docstrings
Roelemans Aug 13, 2020
5e73645
Moved checkState and getErrorStatus from MotorController to MotorCont…
Roelemans Aug 13, 2020
f0c296f
Clang
Roelemans Aug 13, 2020
ea89e8e
Reduce ethercat dependency in naming
Roelemans Aug 14, 2020
03c994a
Merge branch 'develop' into feature/PM-524-add-odrive-option
Roelemans Aug 14, 2020
df36bbf
Mock motor controller and fix bugs
Roelemans Aug 14, 2020
5edecb5
Revert generalise ethercat naming
Roelemans Aug 21, 2020
58fbd2f
Use Ampere instead of IU for torque, and change input/return type of …
Roelemans Aug 21, 2020
855e436
Rename variable in header
Roelemans Aug 21, 2020
e68a574
Return smart pointer instead of reference and minor fixes
Roelemans Aug 24, 2020
0a1c16a
Return smart pointer instead of reference and minor fixes #2
Roelemans Aug 24, 2020
c49c6b3
Merge branch 'develop' into feature/PM-524-add-odrive-option
Roelemans Aug 25, 2020
0fbe358
Create slave_list object
Roelemans Aug 25, 2020
4f66858
Pass a slave list to ethercat master
Roelemans Aug 25, 2020
b48674d
Fix tests
Roelemans Aug 25, 2020
81f0db4
Fix tests
Roelemans Aug 25, 2020
41257c8
Remove initialize from Joint and MotorController
Roelemans Aug 25, 2020
79a93a3
Move hasValidSlaves() to ethercat master
Roelemans Aug 25, 2020
1e55adb
Remove getSlaveIndex from MotorController
Roelemans Aug 25, 2020
ea171c0
Actually use make_shared for shared_ptrs
Roelemans Aug 26, 2020
9b5cc5c
Add docstring
Roelemans Aug 26, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions march_hardware/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,13 @@ add_library(${PROJECT_NAME}
include/${PROJECT_NAME}/ethercat/pdo_types.h
include/${PROJECT_NAME}/ethercat/sdo_interface.h
include/${PROJECT_NAME}/ethercat/slave.h
include/${PROJECT_NAME}/imotioncube/actuation_mode.h
include/${PROJECT_NAME}/imotioncube/imotioncube.h
include/${PROJECT_NAME}/imotioncube/imotioncube_state.h
include/${PROJECT_NAME}/imotioncube/imotioncube_target_state.h
include/${PROJECT_NAME}/motor_controller/actuation_mode.h
include/${PROJECT_NAME}/motor_controller/imotioncube/imotioncube.h
include/${PROJECT_NAME}/motor_controller/imotioncube/imotioncube_states.h
include/${PROJECT_NAME}/motor_controller/imotioncube/imotioncube_state_of_operation.h
include/${PROJECT_NAME}/motor_controller/imotioncube/imotioncube_target_state.h
include/${PROJECT_NAME}/motor_controller/motor_controller.h
include/${PROJECT_NAME}/motor_controller/motor_controller_states.h
include/${PROJECT_NAME}/joint.h
include/${PROJECT_NAME}/march_robot.h
include/${PROJECT_NAME}/power/boot_shutdown_offsets.h
Expand Down Expand Up @@ -123,7 +126,7 @@ if(CATKIN_ENABLE_TESTING)
test/joint_test.cpp
test/mocks/mock_absolute_encoder.h
test/mocks/mock_encoder.h
test/mocks/mock_imotioncube.h
test/mocks/mock_motor_controller.h
test/mocks/mock_incremental_encoder.h
test/mocks/mock_joint.h
test/mocks/mock_pdo_interface.h
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace march
class EthercatMaster
{
public:
EthercatMaster(std::string ifname, int max_slave_index, int cycle_time, int slave_timeout);
EthercatMaster(std::string ifname, std::vector<std::shared_ptr<Slave>>, int cycle_time, int slave_timeout);
~EthercatMaster();

/* Delete copy constructor/assignment since the member thread can not be copied */
Expand All @@ -45,12 +45,20 @@ class EthercatMaster
*/
int getCycleTime() const;

/**
* Returns the largest slave index.
*/
int getMaxSlaveIndex();

bool hasValidSlaves();

/**
* Initializes the ethercat train and starts a thread for the loop.
* @throws HardwareException If not the configured amount of slaves was found
* or they did not all reach operational state
* @returns true if one of the slaves requires resetting ethercat, false otherwise
*/
bool start(std::vector<Joint>& joints);
bool start();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain why the joints parameter has been removed and what the return value of this function indicates?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously, the joints parameter was used by the ethercat master to access the ethercat slaves to call initSdo on each. The EthercatMaster is now passed a list of ethercat slaves at initiation, making joints parameter unnecessary. The return value is now explained in the docstring


/**
* Stops the ethercat loop and joins the thread.
Expand All @@ -67,8 +75,10 @@ class EthercatMaster

/**
* Configures the found slaves to operational state.
*
* @returns true if one of the slaves requires resetting ethercat, false otherwise
*/
bool ethercatSlaveInitiation(std::vector<Joint>& joints);
bool ethercatSlaveInitiation();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain why the joints parameter has been removed and what the return value of this function indicates?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above


/**
* The ethercat train PDO loop. If the working counter is lower than
Expand Down Expand Up @@ -112,6 +122,7 @@ class EthercatMaster
std::atomic<bool> is_operational_;

const std::string ifname_;
std::vector<std::shared_ptr<Slave>> slave_list_;
const int max_slave_index_;
const int cycle_time_ms_;

Expand Down
5 changes: 5 additions & 0 deletions march_hardware/include/march_hardware/ethercat/slave.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ class Slave : public PdoSlaveInterface
this->reset(sdo_slave_interface);
}

virtual bool hasWatchdog()
{
return false;
}

protected:
virtual bool initSdo(SdoSlaveInterface& /* sdo */, int /* cycle_time */)
{
Expand Down
78 changes: 14 additions & 64 deletions march_hardware/include/march_hardware/joint.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
#include <utility>
#include <vector>

#include <march_hardware/imotioncube/imotioncube.h>
#include <march_hardware/motor_controller/imotioncube/imotioncube.h>
#include <march_hardware/power/power_distribution_board.h>
#include <march_hardware/temperature/temperature_ges.h>
#include <march_hardware/imotioncube/imotioncube_state.h>
#include <march_hardware/motor_controller/motor_controller_states.h>

namespace march
{
Expand All @@ -26,107 +26,57 @@ class Joint
/**
* Initializes a Joint with motor controller and without temperature slave.
*/
Joint(std::string name, int net_number, bool allow_actuation, std::unique_ptr<IMotionCube> imc);
Joint(std::string name, int net_number, bool allow_actuation, std::shared_ptr<MotorController> controller);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why has this been changed from a unique_ptr to a shared_ptr?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same reason for the ges, there is now one pointer in EthercatMaster, and one in the MarchRobot


/**
* Initializes a Joint with motor controller and temperature slave.
*/
Joint(std::string name, int net_number, bool allow_actuation, std::unique_ptr<IMotionCube> imc,
std::unique_ptr<TemperatureGES> temperature_ges);
Joint(std::string name, int net_number, bool allow_actuation, std::shared_ptr<MotorController> controller,
std::shared_ptr<TemperatureGES> temperature_ges);

virtual ~Joint() noexcept = default;

/* Delete copy constructor/assignment since the unique_ptr cannot be copied */
/* Delete copy constructor/assignment since the shared_ptr cannot be copied */
Joint(const Joint&) = delete;
Joint& operator=(const Joint&) = delete;

void resetIMotionCube();
void resetMotorController();

/* Delete move assignment since string cannot be move assigned */
Joint(Joint&&) = default;
Joint& operator=(Joint&&) = delete;

bool initialize(int cycle_time);
void prepareActuation();

void actuateRad(double target_position);
void actuateTorque(int16_t target_torque);
void actuateTorque(double target_torque);
void readEncoders(const ros::Duration& elapsed_time);

double getPosition() const;
double getVelocity() const;
double getVoltageVelocity() const;
double getIncrementalPosition() const;
double getAbsolutePosition() const;
int16_t getTorque();
int32_t getAngleIUAbsolute();
int32_t getAngleIUIncremental();
double getVelocityIUAbsolute();
double getVelocityIUIncremental();
double getTorque();
float getTemperature();
IMotionCubeState getIMotionCubeState();
std::unique_ptr<MotorControllerStates> getMotorControllerStates();

std::string getName() const;
int getTemperatureGESSlaveIndex() const;
int getIMotionCubeSlaveIndex() const;
int getNetNumber() const;

ActuationMode getActuationMode() const;

bool hasIMotionCube() const;
bool hasMotorController() const;
Roelemans marked this conversation as resolved.
Show resolved Hide resolved
bool hasTemperatureGES() const;
bool canActuate() const;
bool receivedDataUpdate();
void setAllowActuation(bool allow_actuation);

/** @brief Override comparison operator */
friend bool operator==(const Joint& lhs, const Joint& rhs)
{
return lhs.name_ == rhs.name_ && ((lhs.imc_ && rhs.imc_ && *lhs.imc_ == *rhs.imc_) || (!lhs.imc_ && !rhs.imc_)) &&
((lhs.temperature_ges_ && rhs.temperature_ges_ && *lhs.temperature_ges_ == *rhs.temperature_ges_) ||
(!lhs.temperature_ges_ && !rhs.temperature_ges_)) &&
lhs.allow_actuation_ == rhs.allow_actuation_ &&
lhs.getActuationMode().getValue() == rhs.getActuationMode().getValue();
}

friend bool operator!=(const Joint& lhs, const Joint& rhs)
{
return !(lhs == rhs);
}
/** @brief Override stream operator for clean printing */
friend ::std::ostream& operator<<(std::ostream& os, const Joint& joint)
{
os << "name: " << joint.name_ << ", "
<< "ActuationMode: " << joint.getActuationMode().toString() << ", "
<< "allowActuation: " << joint.allow_actuation_ << ", "
<< "imotioncube: ";
if (joint.imc_)
{
os << *joint.imc_;
}
else
{
os << "none";
}

os << ", temperatureges: ";
if (joint.temperature_ges_)
{
os << *joint.temperature_ges_;
}
else
{
os << "none";
}

return os;
}

private:
const std::string name_;
const int net_number_;
bool allow_actuation_ = false;
float previous_imc_volt_ = 0.0;
float previous_controller_volt_ = 0.0;
float previous_motor_current_ = 0.0;
float previous_motor_volt_ = 0.0;
double previous_absolute_position_ = 0.0;
Expand All @@ -139,8 +89,8 @@ class Joint
double absolute_position_ = 0.0;
double velocity_ = 0.0;

std::unique_ptr<IMotionCube> imc_ = nullptr;
std::unique_ptr<TemperatureGES> temperature_ges_ = nullptr;
std::shared_ptr<MotorController> controller_ = nullptr;
std::shared_ptr<TemperatureGES> temperature_ges_ = nullptr;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why has this been changed to a shared_ptr?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because I now pass a list of ethercat slaves to ethercat_master (so that march_robot does not need to know which joints are ethercat slaves, and because it makes more sense anyway). So now there are two or three pointers to a a Ges, on in the EthercatMaster, and one in one or two of the joints (previously, the two joints had two separate ges objects for the same ges).

};

} // namespace march
Expand Down
45 changes: 7 additions & 38 deletions march_hardware/include/march_hardware/march_robot.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,17 @@ class MarchRobot
::std::vector<Joint> jointList;
urdf::Model urdf_;
EthercatMaster ethercatMaster;
std::unique_ptr<PowerDistributionBoard> pdb_;
std::shared_ptr<PowerDistributionBoard> pdb_;

public:
using iterator = std::vector<Joint>::iterator;

MarchRobot(::std::vector<Joint> jointList, urdf::Model urdf, ::std::string ifName, int ecatCycleTime,
int ecatSlaveTimeout);
MarchRobot(::std::vector<Joint> jointList, urdf::Model urdf, ::std::string ifName,
std::vector<std::shared_ptr<Slave>> slave_list, int ecatCycleTime, int ecatSlaveTimeout);

MarchRobot(::std::vector<Joint> jointList, urdf::Model urdf,
std::unique_ptr<PowerDistributionBoard> powerDistributionBoard, ::std::string ifName, int ecatCycleTime,
int ecatSlaveTimeout);
std::shared_ptr<PowerDistributionBoard> powerDistributionBoard, ::std::string ifName,
std::vector<std::shared_ptr<Slave>> slave_list, int ecatCycleTime, int ecatSlaveTimeout);

~MarchRobot();

Expand All @@ -43,16 +43,14 @@ class MarchRobot
MarchRobot(MarchRobot&&) = delete;
MarchRobot& operator=(MarchRobot&&) = delete;

void resetIMotionCubes();
void resetMotorControllers();

void startEtherCAT(bool reset_imc);
void startEtherCAT(bool reset_motor_controllers);

void stopEtherCAT();

int getMaxSlaveIndex();

bool hasValidSlaves();

bool isEthercatOperational();

std::exception_ptr getLastEthercatException() const noexcept;
Expand All @@ -74,35 +72,6 @@ class MarchRobot
PowerDistributionBoard* getPowerDistributionBoard() const;

const urdf::Model& getUrdf() const;

/** @brief Override comparison operator */
friend bool operator==(const MarchRobot& lhs, const MarchRobot& rhs)
{
if (lhs.jointList.size() != rhs.jointList.size())
{
return false;
}
for (unsigned int i = 0; i < lhs.jointList.size(); i++)
{
const march::Joint& lhsJoint = lhs.jointList.at(i);
const march::Joint& rhsJoint = rhs.jointList.at(i);
if (lhsJoint != rhsJoint)
{
return false;
}
}
return true;
}

/** @brief Override stream operator for clean printing */
friend ::std::ostream& operator<<(std::ostream& os, const MarchRobot& marchRobot)
{
for (unsigned int i = 0; i < marchRobot.jointList.size(); i++)
{
os << marchRobot.jointList.at(i) << "\n";
}
return os;
}
};
} // namespace march
#endif // MARCH_HARDWARE_MARCH_ROBOT_H
Loading