Program Listing for File cia402_data.hpp
↰ Return to documentation for file (/tmp/ws/src/ros2_canopen/canopen_ros2_control/include/canopen_ros2_control/cia402_data.hpp
)
// Copyright (c) 2023, Fraunhofer IPA
// Copyright (c) 2022, StoglRobotics
// Copyright (c) 2022, Stogl Robotics Consulting UG (haftungsbeschränkt) (template)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef CANOPEN_ROS2_CONTROL__CIA402_DATA_HPP_
#define CANOPEN_ROS2_CONTROL__CIA402_DATA_HPP_
#include <yaml-cpp/yaml.h>
#include <cstdint>
#include <memory>
#include <string>
#include "canopen_402_driver/base.hpp"
#include "canopen_402_driver/cia402_driver.hpp"
#include "canopen_ros2_control/helpers.hpp"
#include "hardware_interface/handle.hpp"
#include "hardware_interface/hardware_info.hpp"
#include "hardware_interface/types/hardware_interface_type_values.hpp"
using namespace ros2_canopen;
namespace canopen_ros2_control
{
struct Cia402Data
{
uint8_t node_id;
std::string joint_name;
std::shared_ptr<ros2_canopen::Cia402Driver> driver;
std::map<std::string, ros2_canopen::MotorBase::OperationMode> command_interface_to_operation_mode;
std::vector<std::string> interfaces;
std::vector<std::string> interfaces_to_start;
std::vector<std::string> interfaces_to_running;
std::vector<std::string> interfaces_to_stop;
YAML::Node config;
// FROM MOTOR
double actual_position = std::numeric_limits<double>::quiet_NaN();
double actual_velocity = std::numeric_limits<double>::quiet_NaN();
// TO MOTOR
double target_position = std::numeric_limits<double>::quiet_NaN();
double target_velocity = std::numeric_limits<double>::quiet_NaN();
double target_torque = std::numeric_limits<double>::quiet_NaN();
bool init_data(hardware_interface::ComponentInfo & joint, std::string device_dump)
{
joint_name = joint.name;
auto config = YAML::Load(device_dump);
if (!config["node_id"])
{
RCLCPP_ERROR(rclcpp::get_logger(joint_name), "No node id for '%s'", joint.name.c_str());
return false;
}
node_id = config["node_id"].as<uint16_t>();
RCLCPP_ERROR(
rclcpp::get_logger(joint_name), "Node id for '%s' is '%u'", joint.name.c_str(), node_id);
if (config["position_mode"])
{
auto position_mode =
(ros2_canopen::MotorBase::OperationMode)config["position_mode"].as<uint>();
RCLCPP_INFO(
rclcpp::get_logger(joint_name), "Registered position_mode '%u' for '%s'", position_mode,
joint.name.c_str());
command_interface_to_operation_mode.emplace(
std::pair(joint.name + "/" + "position", position_mode));
}
if (config["velocity_mode"])
{
auto velocity_mode =
(ros2_canopen::MotorBase::OperationMode)config["velocity_mode"].as<uint>();
RCLCPP_INFO(
rclcpp::get_logger(joint_name), "Registered velocity_mode '%u' for '%s'", velocity_mode,
joint.name.c_str());
command_interface_to_operation_mode.emplace(
std::pair(joint.name + "/" + "velocity", velocity_mode));
}
if (config["effort_mode"])
{
auto effort_mode = (ros2_canopen::MotorBase::OperationMode)config["effort_mode"].as<uint>();
RCLCPP_INFO(
rclcpp::get_logger(joint_name), "Registered effort_mode '%u' for '%s'", effort_mode,
joint.name.c_str());
command_interface_to_operation_mode.emplace(
std::pair(joint.name + "/" + "effort", effort_mode));
}
return true;
}
void export_state_interface(std::vector<hardware_interface::StateInterface> & state_interfaces)
{
// actual position
state_interfaces.emplace_back(hardware_interface::StateInterface(
joint_name, hardware_interface::HW_IF_POSITION, &actual_position));
// actual speed
state_interfaces.emplace_back(hardware_interface::StateInterface(
joint_name, hardware_interface::HW_IF_VELOCITY, &actual_velocity));
}
void export_command_interface(
std::vector<hardware_interface::CommandInterface> & command_interfaces)
{
if (
command_interface_to_operation_mode.find(joint_name + "/" + "position") !=
command_interface_to_operation_mode.end())
{
// target position
command_interfaces.emplace_back(
joint_name, hardware_interface::HW_IF_POSITION, &target_position);
interfaces.push_back(joint_name + "/" + "position");
}
if (
command_interface_to_operation_mode.find(joint_name + "/" + "velocity") !=
command_interface_to_operation_mode.end())
{
// target velocity
command_interfaces.emplace_back(
joint_name, hardware_interface::HW_IF_VELOCITY, &target_velocity);
interfaces.push_back(joint_name + "/" + "velocity");
}
if (
command_interface_to_operation_mode.find(joint_name + "/" + "effort") !=
command_interface_to_operation_mode.end())
{
// target effort
command_interfaces.emplace_back(
joint_name, hardware_interface::HW_IF_EFFORT, &target_position);
interfaces.push_back(joint_name + "/" + "effort");
}
}
void read_state()
{
actual_position = driver->get_position();
actual_velocity = driver->get_speed();
}
void write_target()
{
const uint16_t & mode = driver->get_mode();
switch (mode)
{
case MotorBase::No_Mode:
break;
case MotorBase::Profiled_Position:
case MotorBase::Cyclic_Synchronous_Position:
case MotorBase::Interpolated_Position:
driver->set_target(target_position);
break;
case MotorBase::Profiled_Velocity:
case MotorBase::Cyclic_Synchronous_Velocity:
driver->set_target(target_velocity);
break;
case MotorBase::Profiled_Torque:
driver->set_target(target_torque);
break;
default:
RCLCPP_INFO(rclcpp::get_logger("robot_system_interface"), "Mode not supported");
}
}
bool perform_switch()
{
if (interfaces_to_start.size() > 1)
{
RCLCPP_ERROR(
rclcpp::get_logger(joint_name),
"Trying to start multiple command interfaces at once for joint '%s'", joint_name.c_str());
return false;
}
if (interfaces_to_start.size() == 0)
{
return true;
}
auto mode = command_interface_to_operation_mode[interfaces_to_start[0]];
interfaces_to_running.clear();
interfaces_to_running.push_back(interfaces_to_start[0]);
interfaces_to_stop.clear();
interfaces_to_start.clear();
RCLCPP_INFO(
rclcpp::get_logger(joint_name),
"Switching to '%s' command mode with CIA402 operation mode '%u'",
interfaces_to_running[0].c_str(), mode);
return driver->set_operation_mode(mode);
}
bool check_id(uint8_t id)
{
if (node_id == id)
{
return true;
}
return false;
}
};
} // namespace canopen_ros2_control
#endif