feat(motor): initialize motor groups by device entry
This commit is contained in:
parent
708c585f28
commit
f768960ff2
@ -3,8 +3,8 @@ arm {
|
|||||||
id: "right_arm"
|
id: "right_arm"
|
||||||
|
|
||||||
motor {
|
motor {
|
||||||
motor_system_id: "ti5_motors"
|
motor_system_id: "right_arm_can_motors"
|
||||||
motor_group_ids: "right_arm_can"
|
motor_group_ids: "right_arm_can_motors"
|
||||||
dof: 7
|
dof: 7
|
||||||
joint_names: "R_SHOULDER_P"
|
joint_names: "R_SHOULDER_P"
|
||||||
joint_names: "R_SHOULDER_R"
|
joint_names: "R_SHOULDER_R"
|
||||||
|
|||||||
@ -3,8 +3,8 @@ arm {
|
|||||||
id: "mujoco_right_arm"
|
id: "mujoco_right_arm"
|
||||||
|
|
||||||
motor {
|
motor {
|
||||||
motor_system_id: "mujoco_motors"
|
motor_system_id: "right_arm_mujoco_motors"
|
||||||
motor_group_ids: "mujoco_right_arm"
|
motor_group_ids: "right_arm_mujoco_motors"
|
||||||
dof: 7
|
dof: 7
|
||||||
joint_names: "right_arm_J1"
|
joint_names: "right_arm_J1"
|
||||||
joint_names: "right_arm_J2"
|
joint_names: "right_arm_J2"
|
||||||
|
|||||||
@ -3,8 +3,8 @@ arm {
|
|||||||
id: "mujoco_right_arm"
|
id: "mujoco_right_arm"
|
||||||
|
|
||||||
motor {
|
motor {
|
||||||
motor_system_id: "mujoco_motors"
|
motor_system_id: "right_arm_mujoco_motors"
|
||||||
motor_group_ids: "mujoco_right_arm"
|
motor_group_ids: "right_arm_mujoco_motors"
|
||||||
dof: 7
|
dof: 7
|
||||||
joint_names: "R_SHOULDER_P"
|
joint_names: "R_SHOULDER_P"
|
||||||
joint_names: "R_SHOULDER_R"
|
joint_names: "R_SHOULDER_R"
|
||||||
|
|||||||
@ -3,8 +3,8 @@ arm {
|
|||||||
id: "mujoco_right_arm"
|
id: "mujoco_right_arm"
|
||||||
|
|
||||||
motor {
|
motor {
|
||||||
motor_system_id: "mujoco_motors"
|
motor_system_id: "right_arm_mujoco_motors"
|
||||||
motor_group_ids: "mujoco_right_arm"
|
motor_group_ids: "right_arm_mujoco_motors"
|
||||||
dof: 7
|
dof: 7
|
||||||
joint_names: "R_SHOULDER_P"
|
joint_names: "R_SHOULDER_P"
|
||||||
joint_names: "R_SHOULDER_R"
|
joint_names: "R_SHOULDER_R"
|
||||||
|
|||||||
@ -3,8 +3,8 @@ arm {
|
|||||||
id: "right_arm"
|
id: "right_arm"
|
||||||
|
|
||||||
motor {
|
motor {
|
||||||
motor_system_id: "ti5_motors"
|
motor_system_id: "right_arm_can_motors"
|
||||||
motor_group_ids: "right_arm_can"
|
motor_group_ids: "right_arm_can_motors"
|
||||||
dof: 7
|
dof: 7
|
||||||
joint_names: "R_SHOULDER_P"
|
joint_names: "R_SHOULDER_P"
|
||||||
joint_names: "R_SHOULDER_R"
|
joint_names: "R_SHOULDER_R"
|
||||||
|
|||||||
@ -2,7 +2,7 @@ motor {
|
|||||||
id: "ethercat_motors"
|
id: "ethercat_motors"
|
||||||
|
|
||||||
motor_groups {
|
motor_groups {
|
||||||
id: "right_arm_ethercat"
|
id: "right_arm_ethercat_motors"
|
||||||
bus_type: MOTOR_BUS_ETHERCAT
|
bus_type: MOTOR_BUS_ETHERCAT
|
||||||
vendor: MOTOR_VENDOR_EYOU
|
vendor: MOTOR_VENDOR_EYOU
|
||||||
protocol: MOTOR_PROTOCOL_ETHERCAT_CIA402
|
protocol: MOTOR_PROTOCOL_ETHERCAT_CIA402
|
||||||
|
|||||||
@ -2,7 +2,7 @@ motor {
|
|||||||
id: "ethercat_motors"
|
id: "ethercat_motors"
|
||||||
|
|
||||||
motor_groups {
|
motor_groups {
|
||||||
id: "right_arm_ethercat"
|
id: "right_arm_ethercat_motors"
|
||||||
bus_type: MOTOR_BUS_ETHERCAT
|
bus_type: MOTOR_BUS_ETHERCAT
|
||||||
vendor: MOTOR_VENDOR_EYOU
|
vendor: MOTOR_VENDOR_EYOU
|
||||||
protocol: MOTOR_PROTOCOL_ETHERCAT_CIA402
|
protocol: MOTOR_PROTOCOL_ETHERCAT_CIA402
|
||||||
|
|||||||
@ -2,7 +2,7 @@ motor {
|
|||||||
id: "mujoco_motors"
|
id: "mujoco_motors"
|
||||||
|
|
||||||
motor_groups {
|
motor_groups {
|
||||||
id: "mujoco_right_arm"
|
id: "right_arm_mujoco_motors"
|
||||||
bus_type: MOTOR_BUS_MUJOCO
|
bus_type: MOTOR_BUS_MUJOCO
|
||||||
vendor: MOTOR_VENDOR_MUJOCO
|
vendor: MOTOR_VENDOR_MUJOCO
|
||||||
protocol: MOTOR_PROTOCOL_MUJOCO
|
protocol: MOTOR_PROTOCOL_MUJOCO
|
||||||
|
|||||||
@ -2,7 +2,7 @@ motor {
|
|||||||
id: "mujoco_motors"
|
id: "mujoco_motors"
|
||||||
|
|
||||||
motor_groups {
|
motor_groups {
|
||||||
id: "mujoco_right_arm"
|
id: "right_arm_mujoco_motors"
|
||||||
bus_type: MOTOR_BUS_MUJOCO
|
bus_type: MOTOR_BUS_MUJOCO
|
||||||
vendor: MOTOR_VENDOR_MUJOCO
|
vendor: MOTOR_VENDOR_MUJOCO
|
||||||
protocol: MOTOR_PROTOCOL_MUJOCO
|
protocol: MOTOR_PROTOCOL_MUJOCO
|
||||||
|
|||||||
@ -2,7 +2,7 @@ motor {
|
|||||||
id: "ti5_motors"
|
id: "ti5_motors"
|
||||||
|
|
||||||
motor_groups {
|
motor_groups {
|
||||||
id: "left_arm_can"
|
id: "left_arm_can_motors"
|
||||||
bus_type: MOTOR_BUS_CAN
|
bus_type: MOTOR_BUS_CAN
|
||||||
vendor: MOTOR_VENDOR_TI5
|
vendor: MOTOR_VENDOR_TI5
|
||||||
protocol: MOTOR_PROTOCOL_CANOPEN
|
protocol: MOTOR_PROTOCOL_CANOPEN
|
||||||
@ -26,7 +26,7 @@ motor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
motor_groups {
|
motor_groups {
|
||||||
id: "right_arm_can"
|
id: "right_arm_can_motors"
|
||||||
bus_type: MOTOR_BUS_CAN
|
bus_type: MOTOR_BUS_CAN
|
||||||
vendor: MOTOR_VENDOR_TI5
|
vendor: MOTOR_VENDOR_TI5
|
||||||
protocol: MOTOR_PROTOCOL_CANOPEN
|
protocol: MOTOR_PROTOCOL_CANOPEN
|
||||||
@ -56,7 +56,7 @@ motor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
motor_groups {
|
motor_groups {
|
||||||
id: "head_can"
|
id: "head_can_motors"
|
||||||
bus_type: MOTOR_BUS_CAN
|
bus_type: MOTOR_BUS_CAN
|
||||||
vendor: MOTOR_VENDOR_TI5
|
vendor: MOTOR_VENDOR_TI5
|
||||||
protocol: MOTOR_PROTOCOL_CANOPEN
|
protocol: MOTOR_PROTOCOL_CANOPEN
|
||||||
@ -78,7 +78,7 @@ motor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
motor_groups {
|
motor_groups {
|
||||||
id: "waist_can"
|
id: "waist_can_motors"
|
||||||
bus_type: MOTOR_BUS_CAN
|
bus_type: MOTOR_BUS_CAN
|
||||||
vendor: MOTOR_VENDOR_TI5
|
vendor: MOTOR_VENDOR_TI5
|
||||||
protocol: MOTOR_PROTOCOL_CANOPEN
|
protocol: MOTOR_PROTOCOL_CANOPEN
|
||||||
|
|||||||
@ -2,8 +2,6 @@ device_manager {
|
|||||||
name: "cmvr_es"
|
name: "cmvr_es"
|
||||||
version: "0.1"
|
version: "0.1"
|
||||||
description: "cmvr edge system version 0.1"
|
description: "cmvr edge system version 0.1"
|
||||||
init_all_motors_when_no_active_joints: true
|
|
||||||
|
|
||||||
devices {
|
devices {
|
||||||
id: "mujoco_world"
|
id: "mujoco_world"
|
||||||
type: DEVICE_TYPE_MUJOCO_WORLD
|
type: DEVICE_TYPE_MUJOCO_WORLD
|
||||||
@ -12,7 +10,7 @@ device_manager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
devices {
|
devices {
|
||||||
id: "mujoco_motors"
|
id: "right_arm_mujoco_motors"
|
||||||
type: DEVICE_TYPE_MOTOR_SYSTEM
|
type: DEVICE_TYPE_MOTOR_SYSTEM
|
||||||
config_file: "devices/motor/mujoco_motors.pb.txt"
|
config_file: "devices/motor/mujoco_motors.pb.txt"
|
||||||
enable: true
|
enable: true
|
||||||
@ -76,14 +74,35 @@ device_manager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
devices {
|
devices {
|
||||||
id: "ti5_motors"
|
id: "left_arm_can_motors"
|
||||||
type: DEVICE_TYPE_MOTOR_SYSTEM
|
type: DEVICE_TYPE_MOTOR_SYSTEM
|
||||||
config_file: "devices/motor/ti5_motors.pb.txt"
|
config_file: "devices/motor/ti5_motors.pb.txt"
|
||||||
enable: false
|
enable: false
|
||||||
}
|
}
|
||||||
|
|
||||||
devices {
|
devices {
|
||||||
id: "ethercat_motors"
|
id: "right_arm_can_motors"
|
||||||
|
type: DEVICE_TYPE_MOTOR_SYSTEM
|
||||||
|
config_file: "devices/motor/ti5_motors.pb.txt"
|
||||||
|
enable: false
|
||||||
|
}
|
||||||
|
|
||||||
|
devices {
|
||||||
|
id: "head_can_motors"
|
||||||
|
type: DEVICE_TYPE_MOTOR_SYSTEM
|
||||||
|
config_file: "devices/motor/ti5_motors.pb.txt"
|
||||||
|
enable: false
|
||||||
|
}
|
||||||
|
|
||||||
|
devices {
|
||||||
|
id: "waist_can_motors"
|
||||||
|
type: DEVICE_TYPE_MOTOR_SYSTEM
|
||||||
|
config_file: "devices/motor/ti5_motors.pb.txt"
|
||||||
|
enable: false
|
||||||
|
}
|
||||||
|
|
||||||
|
devices {
|
||||||
|
id: "right_arm_ethercat_motors"
|
||||||
type: DEVICE_TYPE_MOTOR_SYSTEM
|
type: DEVICE_TYPE_MOTOR_SYSTEM
|
||||||
config_file: "devices/motor/ethercat_motors.pb.txt"
|
config_file: "devices/motor/ethercat_motors.pb.txt"
|
||||||
enable: false
|
enable: false
|
||||||
|
|||||||
@ -13,7 +13,6 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <unordered_set>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -159,18 +158,10 @@ protected:
|
|||||||
"cmvr-es/config/devices/motor/mujoco_motors_gen2.pb.txt").string(),
|
"cmvr-es/config/devices/motor/mujoco_motors_gen2.pb.txt").string(),
|
||||||
&motor_root_config));
|
&motor_root_config));
|
||||||
|
|
||||||
std::unordered_set<std::string> right_arm_joints;
|
|
||||||
for (const auto* joint_name : kJointNames) {
|
|
||||||
right_arm_joints.insert(joint_name);
|
|
||||||
}
|
|
||||||
MotorManager::clearActiveJoints();
|
|
||||||
MotorManager::setActiveJoints(
|
|
||||||
"mujoco_motors", {{"mujoco_right_arm", std::move(right_arm_joints)}});
|
|
||||||
|
|
||||||
motor_system_ = std::make_shared<MotorManager>(
|
motor_system_ = std::make_shared<MotorManager>(
|
||||||
"mujoco_motors", motor_root_config.motor());
|
"right_arm_mujoco_motors", motor_root_config.motor(), "right_arm_mujoco_motors");
|
||||||
ASSERT_TRUE(motor_system_->init());
|
ASSERT_TRUE(motor_system_->init());
|
||||||
world_ = MotorManager::mujocoWorldFor("mujoco_motors");
|
world_ = MotorManager::mujocoWorldFor("right_arm_mujoco_motors");
|
||||||
ASSERT_TRUE(world_);
|
ASSERT_TRUE(world_);
|
||||||
ASSERT_TRUE(world_->isLoaded());
|
ASSERT_TRUE(world_->isLoaded());
|
||||||
|
|
||||||
@ -208,7 +199,6 @@ protected:
|
|||||||
world_device_->stop();
|
world_device_->stop();
|
||||||
}
|
}
|
||||||
DeviceManager::destroyInstance();
|
DeviceManager::destroyInstance();
|
||||||
MotorManager::clearActiveJoints();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::filesystem::path project_root_;
|
std::filesystem::path project_root_;
|
||||||
|
|||||||
@ -10,7 +10,6 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <unordered_set>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -147,17 +146,10 @@ protected:
|
|||||||
(project_root_ / "cmvr-es/config/devices/motor/mujoco_motors.pb.txt").string(),
|
(project_root_ / "cmvr-es/config/devices/motor/mujoco_motors.pb.txt").string(),
|
||||||
&motor_root_config));
|
&motor_root_config));
|
||||||
|
|
||||||
std::unordered_set<std::string> right_arm_joints;
|
motor_system_ = std::make_shared<MotorManager>(
|
||||||
for (const auto* joint_name : kJointNames) {
|
"right_arm_mujoco_motors", motor_root_config.motor(), "right_arm_mujoco_motors");
|
||||||
right_arm_joints.insert(joint_name);
|
|
||||||
}
|
|
||||||
MotorManager::clearActiveJoints();
|
|
||||||
MotorManager::setActiveJoints(
|
|
||||||
"mujoco_motors", {{"mujoco_right_arm", std::move(right_arm_joints)}});
|
|
||||||
|
|
||||||
motor_system_ = std::make_shared<MotorManager>("mujoco_motors", motor_root_config.motor());
|
|
||||||
ASSERT_NO_THROW(motor_system_->init());
|
ASSERT_NO_THROW(motor_system_->init());
|
||||||
world_ = MotorManager::mujocoWorldFor("mujoco_motors");
|
world_ = MotorManager::mujocoWorldFor("right_arm_mujoco_motors");
|
||||||
ASSERT_TRUE(world_);
|
ASSERT_TRUE(world_);
|
||||||
ASSERT_TRUE(world_->isLoaded());
|
ASSERT_TRUE(world_->isLoaded());
|
||||||
|
|
||||||
@ -187,7 +179,6 @@ protected:
|
|||||||
if (world_device_) {
|
if (world_device_) {
|
||||||
world_device_->stop();
|
world_device_->stop();
|
||||||
}
|
}
|
||||||
MotorManager::clearActiveJoints();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::filesystem::path project_root_;
|
std::filesystem::path project_root_;
|
||||||
|
|||||||
@ -21,7 +21,7 @@
|
|||||||
namespace cmvr::device {
|
namespace cmvr::device {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr const char* kMotorManagerId = "ethercat_motors";
|
constexpr const char* kMotorManagerId = "right_arm_ethercat_motors";
|
||||||
constexpr const char* kMotorConfigFile =
|
constexpr const char* kMotorConfigFile =
|
||||||
"devices/motor/ethercat_motors_four_real_test.pb.txt";
|
"devices/motor/ethercat_motors_four_real_test.pb.txt";
|
||||||
constexpr std::array<int, 4> kFourMotorIds{1, 2, 3, 4};
|
constexpr std::array<int, 4> kFourMotorIds{1, 2, 3, 4};
|
||||||
@ -169,8 +169,6 @@ config::DeviceManagerConfig createEthercatOnlyDeviceManagerConfig()
|
|||||||
config::DeviceManagerConfig config;
|
config::DeviceManagerConfig config;
|
||||||
config.set_name("eyou_motor_device_manager_real_test");
|
config.set_name("eyou_motor_device_manager_real_test");
|
||||||
config.set_version("test");
|
config.set_version("test");
|
||||||
config.set_init_all_motors_when_no_active_joints(true);
|
|
||||||
|
|
||||||
auto* motor_entry = config.add_devices();
|
auto* motor_entry = config.add_devices();
|
||||||
motor_entry->set_id(kMotorManagerId);
|
motor_entry->set_id(kMotorManagerId);
|
||||||
motor_entry->set_type(config::DeviceConfigEntry::DEVICE_TYPE_MOTOR_SYSTEM);
|
motor_entry->set_type(config::DeviceConfigEntry::DEVICE_TYPE_MOTOR_SYSTEM);
|
||||||
|
|||||||
@ -5,7 +5,6 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_set>
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -32,7 +31,9 @@ class AbstractMotorBusRuntime;
|
|||||||
class MotorManager final : public AbstractDevice,
|
class MotorManager final : public AbstractDevice,
|
||||||
public std::enable_shared_from_this<MotorManager> {
|
public std::enable_shared_from_this<MotorManager> {
|
||||||
public:
|
public:
|
||||||
MotorManager(std::string id, const config::MotorConfig& cfg);
|
MotorManager(std::string id,
|
||||||
|
const config::MotorConfig& cfg,
|
||||||
|
std::string selected_group_id);
|
||||||
~MotorManager() override;
|
~MotorManager() override;
|
||||||
|
|
||||||
DeviceKind kind() const noexcept override { return DeviceKind::MotorSystem; }
|
DeviceKind kind() const noexcept override { return DeviceKind::MotorSystem; }
|
||||||
@ -56,16 +57,7 @@ public:
|
|||||||
|
|
||||||
static std::shared_ptr<MotorManager> managerFor(const std::string& id);
|
static std::shared_ptr<MotorManager> managerFor(const std::string& id);
|
||||||
static std::shared_ptr<simulate::MujocoWorld> mujocoWorldFor(const std::string& id);
|
static std::shared_ptr<simulate::MujocoWorld> mujocoWorldFor(const std::string& id);
|
||||||
static void setActiveJoints(const std::string& motor_manager_id,
|
|
||||||
std::unordered_map<std::string, std::unordered_set<std::string>> group_joints);
|
|
||||||
static void clearActiveJoints();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using ActiveJointSelection = std::unordered_map<std::string, std::unordered_set<std::string>>;
|
|
||||||
|
|
||||||
bool selectActiveMotors_(const std::string& group_name,
|
|
||||||
const google::protobuf::RepeatedPtrField<config::MotorConfigItem>& source,
|
|
||||||
std::vector<config::MotorConfigItem>& selected) const;
|
|
||||||
bool applyConfiguredJointLimits_(const config::MotorGroupConfig& group_cfg,
|
bool applyConfiguredJointLimits_(const config::MotorGroupConfig& group_cfg,
|
||||||
std::vector<config::MotorConfigItem>& selected) const;
|
std::vector<config::MotorConfigItem>& selected) const;
|
||||||
std::shared_ptr<AbstractMotorBusRuntime> createBusRuntime_(
|
std::shared_ptr<AbstractMotorBusRuntime> createBusRuntime_(
|
||||||
@ -89,6 +81,7 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
config::MotorConfig cfg_;
|
config::MotorConfig cfg_;
|
||||||
|
std::string selected_group_id_;
|
||||||
std::vector<std::shared_ptr<AbstractMotorBusRuntime>> bus_runtimes_;
|
std::vector<std::shared_ptr<AbstractMotorBusRuntime>> bus_runtimes_;
|
||||||
mutable std::mutex motors_mutex_;
|
mutable std::mutex motors_mutex_;
|
||||||
std::unordered_map<std::uint8_t, std::shared_ptr<AbstractMotor>> motors_by_id_;
|
std::unordered_map<std::uint8_t, std::shared_ptr<AbstractMotor>> motors_by_id_;
|
||||||
@ -98,7 +91,6 @@ private:
|
|||||||
static std::mutex registry_mutex_;
|
static std::mutex registry_mutex_;
|
||||||
static std::unordered_map<std::string, std::weak_ptr<MotorManager>> managers_;
|
static std::unordered_map<std::string, std::weak_ptr<MotorManager>> managers_;
|
||||||
static std::unordered_map<std::string, std::weak_ptr<simulate::MujocoWorld>> mujoco_world_registry_;
|
static std::unordered_map<std::string, std::weak_ptr<simulate::MujocoWorld>> mujoco_world_registry_;
|
||||||
static std::unordered_map<std::string, ActiveJointSelection> active_joints_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace cmvr::device
|
} // namespace cmvr::device
|
||||||
|
|||||||
@ -28,17 +28,14 @@ namespace cmvr::device {
|
|||||||
std::mutex MotorManager::registry_mutex_;
|
std::mutex MotorManager::registry_mutex_;
|
||||||
std::unordered_map<std::string, std::weak_ptr<MotorManager>> MotorManager::managers_;
|
std::unordered_map<std::string, std::weak_ptr<MotorManager>> MotorManager::managers_;
|
||||||
std::unordered_map<std::string, std::weak_ptr<simulate::MujocoWorld>> MotorManager::mujoco_world_registry_;
|
std::unordered_map<std::string, std::weak_ptr<simulate::MujocoWorld>> MotorManager::mujoco_world_registry_;
|
||||||
std::unordered_map<std::string, MotorManager::ActiveJointSelection> MotorManager::active_joints_;
|
|
||||||
|
|
||||||
MotorManager::MotorManager(std::string id, const config::MotorConfig& cfg)
|
MotorManager::MotorManager(std::string id,
|
||||||
: cfg_(cfg)
|
const config::MotorConfig& cfg,
|
||||||
|
std::string selected_group_id)
|
||||||
|
: cfg_(cfg),
|
||||||
|
selected_group_id_(std::move(selected_group_id))
|
||||||
{
|
{
|
||||||
id_ = std::move(id);
|
id_ = std::move(id);
|
||||||
if (!cfg_.id().empty() && cfg_.id() != id_) {
|
|
||||||
CMVR_LOG(ERROR) << "[MotorManager] config id '" << cfg_.id()
|
|
||||||
<< "' does not match device id '" << id_ << "'";
|
|
||||||
id_.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MotorManager::~MotorManager() = default;
|
MotorManager::~MotorManager() = default;
|
||||||
@ -52,6 +49,14 @@ bool MotorManager::init()
|
|||||||
CMVR_LOG(ERROR) << "[MotorManager] id is empty";
|
CMVR_LOG(ERROR) << "[MotorManager] id is empty";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (selected_group_id_.empty()) {
|
||||||
|
CMVR_LOG(ERROR) << "[MotorManager] selected motor group id is empty: " << id_;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cfg_.motor_groups_size() == 0) {
|
||||||
|
CMVR_LOG(ERROR) << "[MotorManager] no motor groups configured: " << id_;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bus_runtimes_.clear();
|
bus_runtimes_.clear();
|
||||||
bus_runtimes_.reserve(static_cast<std::size_t>(cfg_.motor_groups_size()));
|
bus_runtimes_.reserve(static_cast<std::size_t>(cfg_.motor_groups_size()));
|
||||||
@ -62,25 +67,27 @@ bool MotorManager::init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool all_ok = true;
|
bool all_ok = true;
|
||||||
|
std::size_t selected_group_count = 0;
|
||||||
for (const auto& motor_group_cfg : cfg_.motor_groups()) {
|
for (const auto& motor_group_cfg : cfg_.motor_groups()) {
|
||||||
const auto& group_name = motor_group_cfg.id();
|
const auto& group_name = motor_group_cfg.id();
|
||||||
if (group_name.empty()) {
|
if (group_name != selected_group_id_) {
|
||||||
CMVR_LOG(ERROR) << "[MotorManager] motor group id is empty in manager: " << id_;
|
|
||||||
all_ok = false;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
++selected_group_count;
|
||||||
if (!motor_group_cfg.has_motors()) {
|
if (!motor_group_cfg.has_motors()) {
|
||||||
CMVR_LOG(ERROR) << "[MotorManager] motor group missing motors: " << group_name;
|
CMVR_LOG(ERROR) << "[MotorManager] motor group missing motors: " << group_name;
|
||||||
all_ok = false;
|
all_ok = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<config::MotorConfigItem> selected_motor_cfgs;
|
if (motor_group_cfg.motors().motors_size() == 0) {
|
||||||
const bool selected_active_group = selectActiveMotors_(
|
CMVR_LOG(ERROR) << "[MotorManager] motor group has no motors: " << group_name;
|
||||||
group_name, motor_group_cfg.motors().motors(), selected_motor_cfgs);
|
all_ok = false;
|
||||||
if (!selected_active_group) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
std::vector<config::MotorConfigItem> selected_motor_cfgs(
|
||||||
|
motor_group_cfg.motors().motors().begin(),
|
||||||
|
motor_group_cfg.motors().motors().end());
|
||||||
|
|
||||||
if (!applyConfiguredJointLimits_(motor_group_cfg, selected_motor_cfgs)) {
|
if (!applyConfiguredJointLimits_(motor_group_cfg, selected_motor_cfgs)) {
|
||||||
all_ok = false;
|
all_ok = false;
|
||||||
@ -137,6 +144,12 @@ bool MotorManager::init()
|
|||||||
bus_runtimes_.push_back(std::move(bus_runtime));
|
bus_runtimes_.push_back(std::move(bus_runtime));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (selected_group_count != 1) {
|
||||||
|
CMVR_LOG(ERROR) << "[MotorManager] selected motor group '" << selected_group_id_
|
||||||
|
<< "' must occur exactly once in config: " << id_;
|
||||||
|
all_ok = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!all_ok) {
|
if (!all_ok) {
|
||||||
for (auto& bus_runtime : bus_runtimes_) {
|
for (auto& bus_runtime : bus_runtimes_) {
|
||||||
if (bus_runtime) {
|
if (bus_runtime) {
|
||||||
@ -299,68 +312,6 @@ std::shared_ptr<simulate::MujocoWorld> MotorManager::mujocoWorldFor(const std::s
|
|||||||
return it->second.lock();
|
return it->second.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MotorManager::setActiveJoints(const std::string& motor_manager_id,
|
|
||||||
ActiveJointSelection group_joints)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(registry_mutex_);
|
|
||||||
active_joints_[motor_manager_id] = std::move(group_joints);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MotorManager::clearActiveJoints()
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(registry_mutex_);
|
|
||||||
active_joints_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MotorManager::selectActiveMotors_(
|
|
||||||
const std::string& group_name,
|
|
||||||
const google::protobuf::RepeatedPtrField<config::MotorConfigItem>& source,
|
|
||||||
std::vector<config::MotorConfigItem>& selected) const
|
|
||||||
{
|
|
||||||
selected.clear();
|
|
||||||
|
|
||||||
ActiveJointSelection selection;
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(registry_mutex_);
|
|
||||||
const auto it = active_joints_.find(id_);
|
|
||||||
if (it != active_joints_.end()) {
|
|
||||||
selection = it->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selection.empty()) {
|
|
||||||
CMVR_LOG(WARNING) << "[MotorManager] No active joints selected for motor manager " << id_
|
|
||||||
<< ", motor group " << group_name << " will not initialize motors.";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto group_it = selection.find(group_name);
|
|
||||||
if (group_it == selection.end() || group_it->second.empty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& motor_cfg : source) {
|
|
||||||
if (group_it->second.count(motor_cfg.joint_name()) > 0) {
|
|
||||||
selected.push_back(motor_cfg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selected.size() != group_it->second.size()) {
|
|
||||||
std::unordered_set<std::string> found;
|
|
||||||
for (const auto& motor_cfg : selected) {
|
|
||||||
found.insert(motor_cfg.joint_name());
|
|
||||||
}
|
|
||||||
for (const auto& joint_name : group_it->second) {
|
|
||||||
if (found.count(joint_name) == 0) {
|
|
||||||
CMVR_LOG(ERROR) << "[MotorManager] active joint '" << joint_name
|
|
||||||
<< "' not found in motor group '" << group_name << "'";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return !selected.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MotorManager::applyConfiguredJointLimits_(const config::MotorGroupConfig& group_cfg,
|
bool MotorManager::applyConfiguredJointLimits_(const config::MotorGroupConfig& group_cfg,
|
||||||
std::vector<config::MotorConfigItem>& selected) const
|
std::vector<config::MotorConfigItem>& selected) const
|
||||||
{
|
{
|
||||||
|
|||||||
@ -8,7 +8,6 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_set>
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "device_factory.h"
|
#include "device_factory.h"
|
||||||
#include "cmvr/config/device_manager_config/device_manager_config.pb.h"
|
#include "cmvr/config/device_manager_config/device_manager_config.pb.h"
|
||||||
@ -49,7 +48,6 @@ namespace cmvr::device {
|
|||||||
|
|
||||||
explicit DeviceManager(const config::DeviceManagerConfig &cfg);
|
explicit DeviceManager(const config::DeviceManagerConfig &cfg);
|
||||||
void log_device_plan_() const;
|
void log_device_plan_() const;
|
||||||
void pre_scan_robot_arm_dependencies_() const;
|
|
||||||
void init_devices_();
|
void init_devices_();
|
||||||
void configure_mujoco_viewer_pip_();
|
void configure_mujoco_viewer_pip_();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -228,11 +228,11 @@ DeviceFactory::DeviceFactory()
|
|||||||
registerCreator(config::DeviceConfigEntry::DEVICE_TYPE_MOTOR_SYSTEM,
|
registerCreator(config::DeviceConfigEntry::DEVICE_TYPE_MOTOR_SYSTEM,
|
||||||
[](const auto& entry) {
|
[](const auto& entry) {
|
||||||
if (entry.id().empty()) {
|
if (entry.id().empty()) {
|
||||||
CMVR_LOG(ERROR) << "[DeviceFactory]: MotorManager id is required";
|
CMVR_LOG(ERROR) << "[DeviceFactory]: Motor group id is required";
|
||||||
return DeviceRecord{};
|
return DeviceRecord{};
|
||||||
}
|
}
|
||||||
if (entry.config_file().empty()) {
|
if (entry.config_file().empty()) {
|
||||||
CMVR_LOG(ERROR) << "[DeviceFactory]: Empty config_file for MotorManager ID: " << entry.id();
|
CMVR_LOG(ERROR) << "[DeviceFactory]: Empty config_file for motor group ID: " << entry.id();
|
||||||
return DeviceRecord{};
|
return DeviceRecord{};
|
||||||
}
|
}
|
||||||
config::MotorRootConfig root_cfg;
|
config::MotorRootConfig root_cfg;
|
||||||
@ -240,8 +240,27 @@ DeviceFactory::DeviceFactory()
|
|||||||
CMVR_LOG(ERROR) << "[DeviceFactory]: Read device config fail";
|
CMVR_LOG(ERROR) << "[DeviceFactory]: Read device config fail";
|
||||||
return DeviceRecord{};
|
return DeviceRecord{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const config::MotorGroupConfig* selected_group = nullptr;
|
||||||
|
for (const auto& group_cfg : root_cfg.motor().motor_groups()) {
|
||||||
|
if (group_cfg.id() != entry.id()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (selected_group != nullptr) {
|
||||||
|
CMVR_LOG(ERROR) << "[DeviceFactory]: Duplicate motor group id '"
|
||||||
|
<< entry.id() << "' in config: " << entry.config_file();
|
||||||
|
return DeviceRecord{};
|
||||||
|
}
|
||||||
|
selected_group = &group_cfg;
|
||||||
|
}
|
||||||
|
if (selected_group == nullptr) {
|
||||||
|
CMVR_LOG(ERROR) << "[DeviceFactory]: Motor group id '" << entry.id()
|
||||||
|
<< "' not found in config: " << entry.config_file();
|
||||||
|
return DeviceRecord{};
|
||||||
|
}
|
||||||
CMVR_LOG(INFO) << "[DeviceFactory]: Read device config success";
|
CMVR_LOG(INFO) << "[DeviceFactory]: Read device config success";
|
||||||
auto device = std::make_shared<MotorManager>(entry.id(), root_cfg.motor());
|
auto device = std::make_shared<MotorManager>(
|
||||||
|
entry.id(), root_cfg.motor(), entry.id());
|
||||||
DeviceRecord record;
|
DeviceRecord record;
|
||||||
record.id = entry.id();
|
record.id = entry.id();
|
||||||
record.kind = device->kind();
|
record.kind = device->kind();
|
||||||
|
|||||||
@ -18,17 +18,12 @@
|
|||||||
#include "devices/speaker/abstract_speaker.h"
|
#include "devices/speaker/abstract_speaker.h"
|
||||||
#include "simulate/mujoco/mujoco_viewer/include/mujoco_viewer.h"
|
#include "simulate/mujoco/mujoco_viewer/include/mujoco_viewer.h"
|
||||||
#include "common/config/config_files.h"
|
#include "common/config/config_files.h"
|
||||||
#include "cmvr/config/arm_config/arm_config.pb.h"
|
|
||||||
#include "cmvr/config/motor_config/motor_config.pb.h"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace cmvr::device;
|
using namespace cmvr::device;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using GroupJointSelection = std::unordered_map<std::string, std::unordered_set<std::string>>;
|
|
||||||
using MotorJointSelections = std::unordered_map<std::string, GroupJointSelection>;
|
|
||||||
|
|
||||||
void logSection(const char* title)
|
void logSection(const char* title)
|
||||||
{
|
{
|
||||||
CMVR_LOG(INFO) << "---------------- " << title << " ----------------";
|
CMVR_LOG(INFO) << "---------------- " << title << " ----------------";
|
||||||
@ -63,43 +58,6 @@ const char* deviceTypeToString(const cmvr::config::DeviceConfigEntry::DeviceType
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool motorGroupHasJoint(const cmvr::config::MotorGroupConfig& motor_group,
|
|
||||||
const std::string& joint_name)
|
|
||||||
{
|
|
||||||
for (const auto& motor : motor_group.motors().motors()) {
|
|
||||||
if (motor.joint_name() == joint_name) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void addAllMotorJoints(const std::string& motor_system_id,
|
|
||||||
const cmvr::config::MotorRootConfig& root_cfg,
|
|
||||||
MotorJointSelections& selections)
|
|
||||||
{
|
|
||||||
auto& group_selection = selections[motor_system_id];
|
|
||||||
for (const auto& motor_group : root_cfg.motor().motor_groups()) {
|
|
||||||
if (motor_group.id().empty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& selected_joints = group_selection[motor_group.id()];
|
|
||||||
for (const auto& motor : motor_group.motors().motors()) {
|
|
||||||
if (!motor.joint_name().empty()) {
|
|
||||||
selected_joints.insert(motor.joint_name());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (selected_joints.empty()) {
|
|
||||||
group_selection.erase(motor_group.id());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (group_selection.empty()) {
|
|
||||||
selections.erase(motor_system_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
template std::shared_ptr<AbstractAGV> DeviceManager::getDevice(const std::string& device_id);
|
template std::shared_ptr<AbstractAGV> DeviceManager::getDevice(const std::string& device_id);
|
||||||
@ -125,7 +83,6 @@ DeviceManager::DeviceManager(const config::DeviceManagerConfig& cfg) {
|
|||||||
dev_factory_ = std::make_unique<DeviceFactory>();
|
dev_factory_ = std::make_unique<DeviceFactory>();
|
||||||
logSection("Device Plan");
|
logSection("Device Plan");
|
||||||
log_device_plan_();
|
log_device_plan_();
|
||||||
pre_scan_robot_arm_dependencies_();
|
|
||||||
logSection("Initialize Devices");
|
logSection("Initialize Devices");
|
||||||
init_devices_();
|
init_devices_();
|
||||||
configure_mujoco_viewer_pip_();
|
configure_mujoco_viewer_pip_();
|
||||||
@ -150,7 +107,6 @@ DeviceManager& DeviceManager::getInstance() {
|
|||||||
void DeviceManager::destroyInstance() {
|
void DeviceManager::destroyInstance() {
|
||||||
std::lock_guard lock(init_mutex_);
|
std::lock_guard lock(init_mutex_);
|
||||||
instance_.reset();
|
instance_.reset();
|
||||||
MotorManager::clearActiveJoints();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceManager::start(){
|
void DeviceManager::start(){
|
||||||
@ -283,153 +239,6 @@ void DeviceManager::log_device_plan_() const
|
|||||||
CMVR_LOG(INFO) << "[DeviceManager]: Device plan end";
|
CMVR_LOG(INFO) << "[DeviceManager]: Device plan end";
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceManager::pre_scan_robot_arm_dependencies_() const
|
|
||||||
{
|
|
||||||
MotorJointSelections selections;
|
|
||||||
std::unordered_map<std::string, config::MotorRootConfig> motor_roots;
|
|
||||||
|
|
||||||
for (const auto& entry : cfg_.devices()) {
|
|
||||||
if (!entry.enable() || entry.type() != config::DeviceConfigEntry::DEVICE_TYPE_MOTOR_SYSTEM) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (entry.id().empty()) {
|
|
||||||
CMVR_LOG(ERROR) << "[DeviceManager]: Enabled MotorManager device id is empty";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (entry.config_file().empty()) {
|
|
||||||
CMVR_LOG(ERROR) << "[DeviceManager]: Enabled MotorManager config_file is empty: " << entry.id();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
config::MotorRootConfig root_cfg;
|
|
||||||
if (!ConfigHelper::loadConfigFileSilent(entry.config_file(), root_cfg)) {
|
|
||||||
CMVR_LOG(ERROR) << "[DeviceManager]: Failed to load motor config: " << entry.config_file();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!root_cfg.motor().id().empty() && root_cfg.motor().id() != entry.id()) {
|
|
||||||
CMVR_LOG(ERROR) << "[DeviceManager]: MotorManager entry id '" << entry.id()
|
|
||||||
<< "' does not match config id '" << root_cfg.motor().id() << "'";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
motor_roots.emplace(entry.id(), std::move(root_cfg));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& entry : cfg_.devices()) {
|
|
||||||
if (!entry.enable() || entry.type() != config::DeviceConfigEntry::DEVICE_TYPE_ROBOT_ARM) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (entry.id().empty()) {
|
|
||||||
CMVR_LOG(ERROR) << "[DeviceManager]: Enabled RobotArm device id is empty";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (entry.config_file().empty()) {
|
|
||||||
CMVR_LOG(ERROR) << "[DeviceManager]: Enabled RobotArm config_file is empty: " << entry.id();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
config::ArmRootConfig root_cfg;
|
|
||||||
if (!ConfigHelper::loadConfigFileSilent(entry.config_file(), root_cfg)) {
|
|
||||||
CMVR_LOG(ERROR) << "[DeviceManager]: Failed to load arm config: " << entry.config_file();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const config::RobotArmConfig* arm_cfg = nullptr;
|
|
||||||
for (const auto& candidate : root_cfg.arm().robot_arms()) {
|
|
||||||
if (candidate.id() == entry.id()) {
|
|
||||||
arm_cfg = &candidate;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!arm_cfg) {
|
|
||||||
CMVR_LOG(ERROR) << "[DeviceManager]: RobotArm ID '" << entry.id()
|
|
||||||
<< "' not found in config: " << entry.config_file();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arm_cfg->backend_case() == config::RobotArmConfig::kVendor) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (arm_cfg->backend_case() != config::RobotArmConfig::kMotor) {
|
|
||||||
CMVR_LOG(ERROR) << "[DeviceManager]: RobotArm backend is not configured: " << entry.id();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& motor_config = arm_cfg->motor();
|
|
||||||
if (motor_config.motor_system_id().empty()) {
|
|
||||||
CMVR_LOG(ERROR) << "[DeviceManager]: RobotArm missing motor_system_id: " << entry.id();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (motor_config.motor_group_ids_size() == 0) {
|
|
||||||
CMVR_LOG(ERROR) << "[DeviceManager]: RobotArm missing motor_group_ids: " << entry.id();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (motor_config.joint_names_size() == 0) {
|
|
||||||
CMVR_LOG(ERROR) << "[DeviceManager]: RobotArm missing joint_names: " << entry.id();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto motor_root_it = motor_roots.find(motor_config.motor_system_id());
|
|
||||||
if (motor_root_it == motor_roots.end()) {
|
|
||||||
CMVR_LOG(ERROR) << "[DeviceManager]: RobotArm '" << entry.id()
|
|
||||||
<< "' depends on disabled or missing MotorManager: "
|
|
||||||
<< motor_config.motor_system_id();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unordered_set<std::string> allowed_groups;
|
|
||||||
allowed_groups.reserve(static_cast<size_t>(motor_config.motor_group_ids_size()));
|
|
||||||
for (const auto& group_id : motor_config.motor_group_ids()) {
|
|
||||||
if (group_id.empty()) {
|
|
||||||
CMVR_LOG(ERROR) << "[DeviceManager]: RobotArm has empty motor_group_id: " << entry.id();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
allowed_groups.insert(group_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& group_selection = selections[motor_config.motor_system_id()];
|
|
||||||
for (const auto& joint_name : motor_config.joint_names()) {
|
|
||||||
if (joint_name.empty()) {
|
|
||||||
CMVR_LOG(ERROR) << "[DeviceManager]: RobotArm has empty joint_name: " << entry.id();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string matched_group;
|
|
||||||
for (const auto& motor_group : motor_root_it->second.motor().motor_groups()) {
|
|
||||||
const auto& group_id = motor_group.id();
|
|
||||||
if (allowed_groups.count(group_id) == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (motorGroupHasJoint(motor_group, joint_name)) {
|
|
||||||
matched_group = group_id;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (matched_group.empty()) {
|
|
||||||
CMVR_LOG(ERROR) << "[DeviceManager]: RobotArm '" << entry.id()
|
|
||||||
<< "' joint '" << joint_name
|
|
||||||
<< "' not found in configured motor_group_ids";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
group_selection[matched_group].insert(joint_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selections.empty() && cfg_.init_all_motors_when_no_active_joints()) {
|
|
||||||
CMVR_LOG(INFO) << "[DeviceManager]: No active motor joints from RobotArm; "
|
|
||||||
<< "initialize all configured motors because "
|
|
||||||
<< "init_all_motors_when_no_active_joints=true";
|
|
||||||
for (const auto& [motor_system_id, root_cfg] : motor_roots) {
|
|
||||||
addAllMotorJoints(motor_system_id, root_cfg, selections);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MotorManager::clearActiveJoints();
|
|
||||||
for (auto& [motor_system_id, group_selection] : selections) {
|
|
||||||
MotorManager::setActiveJoints(motor_system_id, std::move(group_selection));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeviceManager::init_devices_() {
|
void DeviceManager::init_devices_() {
|
||||||
for (const auto& entry : cfg_.devices()) {
|
for (const auto& entry : cfg_.devices()) {
|
||||||
if (!entry.enable()) {
|
if (!entry.enable()) {
|
||||||
|
|||||||
@ -292,7 +292,7 @@ TEST(TouchScreenTaskTest, RunTouchOnceInMujoco) {
|
|||||||
world_entry->set_config_file("devices/mujoco/mujoco_world.pb.txt");
|
world_entry->set_config_file("devices/mujoco/mujoco_world.pb.txt");
|
||||||
world_entry->set_enable(true);
|
world_entry->set_enable(true);
|
||||||
auto* motor_entry = device_manager_config.add_devices();
|
auto* motor_entry = device_manager_config.add_devices();
|
||||||
motor_entry->set_id("mujoco_motors");
|
motor_entry->set_id("right_arm_mujoco_motors");
|
||||||
motor_entry->set_type(cmvr::config::DeviceConfigEntry::DEVICE_TYPE_MOTOR_SYSTEM);
|
motor_entry->set_type(cmvr::config::DeviceConfigEntry::DEVICE_TYPE_MOTOR_SYSTEM);
|
||||||
motor_entry->set_config_file("devices/motor/mujoco_motors.pb.txt");
|
motor_entry->set_config_file("devices/motor/mujoco_motors.pb.txt");
|
||||||
motor_entry->set_enable(true);
|
motor_entry->set_enable(true);
|
||||||
@ -308,12 +308,12 @@ TEST(TouchScreenTaskTest, RunTouchOnceInMujoco) {
|
|||||||
dexhand_entry->set_enable(true);
|
dexhand_entry->set_enable(true);
|
||||||
|
|
||||||
auto& device_manager = cmvr::device::DeviceManager::getInstance(device_manager_config);
|
auto& device_manager = cmvr::device::DeviceManager::getInstance(device_manager_config);
|
||||||
auto motor_system = device_manager.getDevice<cmvr::device::MotorManager>("mujoco_motors");
|
auto motor_system = device_manager.getDevice<cmvr::device::MotorManager>("right_arm_mujoco_motors");
|
||||||
if (!motor_system) {
|
if (!motor_system) {
|
||||||
CMVR_LOG(ERROR) << "[TouchScreenTaskTest] MotorManager not found: mujoco_motors";
|
CMVR_LOG(ERROR) << "[TouchScreenTaskTest] MotorManager not found: right_arm_mujoco_motors";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto world = cmvr::device::MotorManager::mujocoWorldFor("mujoco_motors");
|
auto world = cmvr::device::MotorManager::mujocoWorldFor("right_arm_mujoco_motors");
|
||||||
if (!world || !world->isLoaded() || !world->isRunning()) {
|
if (!world || !world->isLoaded() || !world->isRunning()) {
|
||||||
CMVR_LOG(ERROR) << "[TouchScreenTaskTest] Mujoco world is not ready: mujoco_world";
|
CMVR_LOG(ERROR) << "[TouchScreenTaskTest] Mujoco world is not ready: mujoco_world";
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
MASTER0_DEVICE="a0:ad:9f:c4:c2:2c"
|
MASTER0_DEVICE="42:e6:6d:44:c1:0f"
|
||||||
DEVICE_MODULES="generic"
|
DEVICE_MODULES="generic"
|
||||||
UPDOWN_INTERFACES="eno1"
|
UPDOWN_INTERFACES="eno1"
|
||||||
|
|||||||
@ -23,6 +23,7 @@ message DeviceConfigEntry {
|
|||||||
DEVICE_TYPE_MUJOCO_VIEWER = 19;
|
DEVICE_TYPE_MUJOCO_VIEWER = 19;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For DEVICE_TYPE_MOTOR_SYSTEM, this is the motor_group id selected from config_file.
|
||||||
string id = 1;
|
string id = 1;
|
||||||
DeviceType type = 2;
|
DeviceType type = 2;
|
||||||
string config_file = 3;
|
string config_file = 3;
|
||||||
@ -30,11 +31,12 @@ message DeviceConfigEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message DeviceManagerConfig {
|
message DeviceManagerConfig {
|
||||||
|
reserved 20;
|
||||||
|
|
||||||
string name = 1;
|
string name = 1;
|
||||||
string version = 2;
|
string version = 2;
|
||||||
string description = 3;
|
string description = 3;
|
||||||
repeated DeviceConfigEntry devices = 4;
|
repeated DeviceConfigEntry devices = 4;
|
||||||
bool init_all_motors_when_no_active_joints = 20;
|
|
||||||
}
|
}
|
||||||
message DeviceManagerRootConfig {
|
message DeviceManagerRootConfig {
|
||||||
DeviceManagerConfig device_manager = 1;
|
DeviceManagerConfig device_manager = 1;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user