Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
2aa058a
multiple masters compatibility added
anubhav-dogra Jun 13, 2025
7397184
Merge pull request #1 from HumanoidTeam/feature/enable_multiple_masters
strezhik-skl Jun 13, 2025
aa30504
temperature error code check for zeroerr drives
anubhav-dogra Jul 8, 2025
2eb4c8a
Merge pull request #2 from HumanoidTeam/feature/temperature_error_cod…
strezhik-skl Jul 8, 2025
195f26e
stop drifting when the controllers are inactive
anubhav-dogra Jul 10, 2025
bb76b15
Merge pull request #3 from HumanoidTeam/fix_drifting_in_CSP
strezhik-skl Jul 11, 2025
083aab1
add optional CONDA_PREFIX to Etherlab files path
strezhik-skl Jul 17, 2025
d8f4502
Merge pull request #4 from HumanoidTeam/HECO-560_integrate_roadkill_r…
anubhav-dogra Jul 17, 2025
1eab6da
add required header for correct build
strezhik-skl Jul 17, 2025
9bd5ca8
Merge pull request #5 from HumanoidTeam/fix_jetson_build
strezhik-skl Jul 17, 2025
077bd53
Added limits functionality for command interfaces
mrafique1 Aug 13, 2025
0e08754
Merge pull request #6 from HumanoidTeam/feature/command_interface_limits
mrafique1 Aug 16, 2025
003a811
The simple-but-effective bug fix
Aug 19, 2025
e45b1be
Merge pull request #7 from HumanoidTeam/feature/bug_fix_joint_droppin…
anubhav-dogra Aug 20, 2025
8cf89d3
add is operational for driver
anubhav-dogra Sep 26, 2025
9c72509
trigger quick stop to all if any one in error
anubhav-dogra Oct 1, 2025
dcb9d4a
allow resetting may be
anubhav-dogra Oct 1, 2025
ef6574a
check status and error code both to prevent boot up chaos
anubhav-dogra Oct 6, 2025
49c1ef6
rever status word check | causes weird sound to the actuators
anubhav-dogra Oct 6, 2025
ed38116
only uses error code, status word is weird
anubhav-dogra Oct 7, 2025
51374d3
check is operational for the whole chain
anubhav-dogra Oct 7, 2025
76fdfd1
undo some change based on hardware testing
Oct 16, 2025
2cc441f
Merge pull request #9 from HumanoidTeam/fix/get_isoperational
robodreamer Oct 16, 2025
e0f55dd
Fixed CiA402 initialized function
robodreamer Oct 24, 2025
fd57b1d
Merge pull request #10 from HumanoidTeam/fix/initialize-function
TobiasJacob Oct 24, 2025
0f2beea
Revert "Fixed CiA402 initialized function"
TobiasJacob Oct 30, 2025
6bc2d34
Merge pull request #12 from HumanoidTeam/revert-init-fix
TobiasJacob Oct 30, 2025
f01ea41
Merge pull request #8 from HumanoidTeam/feature/trigger_error_to_all
anubhav-dogra Nov 3, 2025
23232f0
quick stop toggle config parameter added
anubhav-dogra Nov 6, 2025
f96fbab
Merge pull request #13 from HumanoidTeam/feature/quick_stop_toggle_pl…
anubhav-dogra Nov 6, 2025
5454a95
adding auto state transition command handler
anubhav-dogra Dec 15, 2025
ab90654
Merge pull request #14 from HumanoidTeam/feature/halt_operation_until…
anubhav-dogra Feb 10, 2026
11f7618
valid check and release in destructor
anubhav-dogra Feb 5, 2026
5078367
Merge pull request #15 from HumanoidTeam/fix/load_release_master_vali…
anubhav-dogra Mar 24, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class EthercatDriver : public hardware_interface::SystemInterface
"ethercat_interface", "ethercat_interface::EcSlave"};

int control_frequency_;
ethercat_interface::EcMaster master_;
std::unique_ptr<ethercat_interface::EcMaster> master_;
std::mutex ec_mutex_;
bool activated_;
};
Expand Down
31 changes: 22 additions & 9 deletions ethercat_driver/src/ethercat_driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ CallbackReturn EthercatDriver::on_init(
const std::lock_guard<std::mutex> lock(ec_mutex_);
activated_ = false;

// Parse master_id from hardware parameters
int master_id = 0; // Default to 0 if not specified
if (info_.hardware_parameters.find("master_id") != info_.hardware_parameters.end()) {
master_id = std::stoi(info_.hardware_parameters["master_id"]);
}
RCLCPP_INFO(rclcpp::get_logger("EthercatDriver"), "Master ID: %d", master_id);

// Initialize master with the specified ID
master_ = std::make_unique<ethercat_interface::EcMaster>(master_id);

hw_joint_states_.resize(info_.joints.size());
for (uint j = 0; j < info_.joints.size(); j++) {
hw_joint_states_[j].resize(
Expand Down Expand Up @@ -282,10 +292,10 @@ CallbackReturn EthercatDriver::on_activate(

// start EC and wait until state operative

master_.setCtrlFrequency(control_frequency_);
master_->setCtrlFrequency(control_frequency_);

for (auto i = 0ul; i < ec_modules_.size(); i++) {
master_.addSlave(
master_->addSlave(
std::stod(ec_module_parameters_[i]["alias"]),
std::stod(ec_module_parameters_[i]["position"]),
ec_modules_[i].get());
Expand All @@ -295,7 +305,7 @@ CallbackReturn EthercatDriver::on_activate(
for (auto i = 0ul; i < ec_modules_.size(); i++) {
for (auto & sdo : ec_modules_[i]->sdo_config) {
uint32_t abort_code;
int ret = master_.configSlaveSdo(
int ret = master_->configSlaveSdo(
std::stod(ec_module_parameters_[i]["position"]),
sdo,
&abort_code
Expand All @@ -311,7 +321,7 @@ CallbackReturn EthercatDriver::on_activate(
}
}

if (!master_.activate()) {
if (!master_->activate()) {
RCLCPP_ERROR(rclcpp::get_logger("EthercatDriver"), "Activate EcMaster failed");
return CallbackReturn::ERROR;
}
Expand All @@ -328,7 +338,7 @@ CallbackReturn EthercatDriver::on_activate(
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t, NULL);
// update EtherCAT bus

master_.update();
master_->update();
RCLCPP_INFO(rclcpp::get_logger("EthercatDriver"), "updated!");

// check if operational
Expand All @@ -340,7 +350,7 @@ CallbackReturn EthercatDriver::on_activate(
running = false;
}
// calculate next shot. carry over nanoseconds into microseconds.
t.tv_nsec += master_.getInterval();
t.tv_nsec += master_->getInterval();
while (t.tv_nsec >= 1000000000) {
t.tv_nsec -= 1000000000;
t.tv_sec++;
Expand All @@ -363,8 +373,11 @@ CallbackReturn EthercatDriver::on_deactivate(

RCLCPP_INFO(rclcpp::get_logger("EthercatDriver"), "Stopping ...please wait...");

// Clean up all modules before stopping the master
ec_modules_.clear();

// stop EC and disconnect
master_.stop();
master_->stop();

RCLCPP_INFO(
rclcpp::get_logger("EthercatDriver"), "System successfully stopped!");
Expand All @@ -379,7 +392,7 @@ hardware_interface::return_type EthercatDriver::read(
// try to lock so we can avoid blocking the read/write loop on the lock.
const std::unique_lock<std::mutex> lock(ec_mutex_, std::try_to_lock);
if (lock.owns_lock() && activated_) {
master_.readData();
master_->readData();
}
return hardware_interface::return_type::OK;
}
Expand All @@ -391,7 +404,7 @@ hardware_interface::return_type EthercatDriver::write(
// try to lock so we can avoid blocking the read/write loop on the lock.
const std::unique_lock<std::mutex> lock(ec_mutex_, std::try_to_lock);
if (lock.owns_lock() && activated_) {
master_.writeData();
master_->writeData();
}
return hardware_interface::return_type::OK;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ Each PDO Channel has the following configuration flags:
- Data conversion factor/scale (:code:`type` : :code:`double`).
* - :code:`offset`
- Data offset term (:code:`type` : :code:`double`).
* - :code:`peak_upper_limit`
- Peak Upper limit (:code:`type` : :code:`double`) applied to command_interface as saturation before multiplying factor and adding offset. default value is :code:`6.2831853` (2*PI).
* - :code:`peak_lower_limit`
- Peak Lower limit (:code:`type` : :code:`double`) applied to command_interface as saturation before multiplying factor and adding offset. default value is :code:`-6.2831853` (-2*PI).
* - :code:`peak_limit_multiplier`
- Peak limit multiplier (:code:`type` : :code:`double`) applied to peak limits to scale them slightly below the actual actuator limits (specified in peak upper/lower limits). This is useful to avoid hitting the limits during operation.


.. warning:: For each channel, tags :code:`index`, :code:`sub_index` and :code:`type` are **mandatory** even if the channel is not used in order to fill the data layout expected by the module. All other tags can remain unset.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#define CiA402D_TPDO_POSITION ((uint16_t) 0x6064)
#define CiA402D_TPDO_STATUSWORD ((uint16_t) 0x6041)
#define CiA402D_TPDO_MODE_OF_OPERATION_DISPLAY ((uint16_t) 0x6061)
#define CiA402D_TPDO_ERROR_CODE ((uint16_t) 0x603f)

#include <map>
#include <string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <string>
#include <unordered_map>
#include <limits>
#include <atomic>

#include "yaml-cpp/yaml.h"
#include "ethercat_interface/ec_slave.hpp"
Expand Down Expand Up @@ -51,6 +52,9 @@ class EcCiA402Drive : public GenericEcSlave
int8_t mode_of_operation_ = -1;

protected:
// Global aggregated count of faulted instances (process-wide)
static std::atomic<int> num_faulted_;

uint32_t counter_ = 0;
uint16_t last_status_word_ = -1;
uint16_t status_word_ = 0;
Expand All @@ -60,10 +64,18 @@ class EcCiA402Drive : public GenericEcSlave
bool initialized_ = false;
bool auto_fault_reset_ = false;
bool auto_state_transitions_ = true;
bool auto_state_transitions_cmd_ = false;
bool fault_reset_ = false;
int fault_reset_command_interface_index_ = -1;
bool last_fault_reset_command_ = false;
double last_position_ = std::numeric_limits<double>::quiet_NaN();
bool temperature_fault_detected_ = false;
uint16_t error_code_ = 0;
int auto_state_cmd_index_ = -1;
bool last_auto_state_cmd_ = false;

// Quick stop behavior controls
bool exclude_from_global_quick_stop_ = false; // Do not propagate this drive's faults globally if true

/** returns device state based upon the status_word */
DeviceState deviceState(uint16_t status_word);
Expand Down
Loading