diff --git a/bindings/python/pyRosImpl.cpp b/bindings/python/pyRosImpl.cpp index 35ca1fa..b660e76 100644 --- a/bindings/python/pyRosImpl.cpp +++ b/bindings/python/pyRosImpl.cpp @@ -91,6 +91,8 @@ PYBIND11_MODULE(pyci, m) { .def("setVelocityLimits", &CartesianTask::setVelocityLimits) .def("setAccelerationLimits", &CartesianTask::setAccelerationLimits) .def("getPoseReference", py_task_get_pose_reference) + .def("setIsVelocityLocal", &CartesianTask::setIsVelocityLocal) + .def("isVelocityLocal", &CartesianTask::isVelocityLocal) .def("abort", &CartesianTask::abort); py::class_ #include +#include + namespace XBot { namespace Cartesian { @@ -94,11 +96,14 @@ class ServerApi::CartesianRos : public ServerApi::TaskRos, bool set_safety_lims_cb(cartesian_interface::SetSafetyLimitsRequest& req, cartesian_interface::SetSafetyLimitsResponse& res); + bool use_local_velocity_reference_cb(std_srvs::SetBoolRequest& req, + std_srvs::SetBoolResponse& res); + ros::Publisher _pose_ref_pub, _vel_ref_pub, _acc_ref_pub, _task_info_pub; ros::Subscriber _pose_ref_sub, _vel_ref_sub; - ros::ServiceServer _get_info_srv, _set_base_link_srv, _set_ctrl_srv, _set_safety_srv; + ros::ServiceServer _get_info_srv, _set_base_link_srv, _set_ctrl_srv, _set_safety_srv, _use_local_velocity_reference_srv; CartesianTask::Ptr _cart; diff --git a/include/cartesian_interface/sdk/rt/CartesianRt.h b/include/cartesian_interface/sdk/rt/CartesianRt.h index d3d21f8..f0d5388 100644 --- a/include/cartesian_interface/sdk/rt/CartesianRt.h +++ b/include/cartesian_interface/sdk/rt/CartesianRt.h @@ -26,6 +26,8 @@ class CartesianRt : public virtual CartesianTask, void enableOnlineTrajectoryGeneration() override; bool isSubtaskLocal() const override; + bool isVelocityLocal() const override; + void setIsVelocityLocal(const bool is_velocity_local) override; void getVelocityLimits(double & max_vel_lin, double & max_vel_ang) const override; void getAccelerationLimits(double & max_acc_lin, double & max_acc_ang) const override; void setVelocityLimits(double max_vel_lin, double max_vel_ang) override; @@ -58,7 +60,7 @@ class CartesianRt : public virtual CartesianTask, { ControlType _ctrl_mode; std::string _base_link, _distal_link; - bool _is_body_jacobian; + bool _is_body_jacobian, _is_velocity_local; double _orientation_gain; Eigen::Affine3d _T; Eigen::Affine3d _Tcurr; diff --git a/msg/CartesianTaskInfo.msg b/msg/CartesianTaskInfo.msg index 44272da..4ced7cb 100644 --- a/msg/CartesianTaskInfo.msg +++ b/msg/CartesianTaskInfo.msg @@ -3,6 +3,7 @@ string distal_link string control_mode string state bool use_local_subtasks +bool use_local_velocity float64 max_vel_lin float64 max_vel_ang float64 max_acc_lin diff --git a/src/opensot/task_adapters/OpenSotCartesian.cpp b/src/opensot/task_adapters/OpenSotCartesian.cpp index b51a593..5568c1f 100644 --- a/src/opensot/task_adapters/OpenSotCartesian.cpp +++ b/src/opensot/task_adapters/OpenSotCartesian.cpp @@ -35,7 +35,7 @@ bool OpenSotCartesianAdapter::initialize(const OpenSoT::OptvarHelper& vars) /* Cartesian task specific parameters */ - _opensot_cart->setIsBodyJacobian(_ci_cart->isSubtaskLocal()); + _opensot_cart->rotateToLocal(_ci_cart->isSubtaskLocal()); /* Register observer */ auto this_shared_ptr = std::dynamic_pointer_cast(shared_from_this()); @@ -61,7 +61,13 @@ void OpenSotCartesianAdapter::update(double time, double period) Eigen::Affine3d Tref; Eigen::Vector6d vref; _ci_cart->getPoseReference(Tref, &vref); - _opensot_cart->setReference(Tref, vref*_ctx->params()->getControlPeriod()); + if(_ci_cart->isVelocityLocal()) + { + _opensot_cart->setReference(Tref); + _opensot_cart->setVelocityLocalReference(vref*_ctx->params()->getControlPeriod()); + } + else + _opensot_cart->setReference(Tref, vref*_ctx->params()->getControlPeriod()); } bool OpenSotCartesianAdapter::onBaseLinkChanged() diff --git a/src/problem/impl/Cartesian.cpp b/src/problem/impl/Cartesian.cpp index 259a99a..cfc0648 100644 --- a/src/problem/impl/Cartesian.cpp +++ b/src/problem/impl/Cartesian.cpp @@ -86,7 +86,8 @@ CartesianTaskImpl::CartesianTaskImpl(YAML::Node task_node, Context::ConstPtr con _state(State::Online), _vref_time_to_live(-1.0), _orientation_gain(1.0), - _is_body_jacobian(false) + _is_body_jacobian(false), + _is_velocity_local(false) { bool is_com = task_node["type"].as() == "Com"; @@ -108,6 +109,11 @@ CartesianTaskImpl::CartesianTaskImpl(YAML::Node task_node, Context::ConstPtr con _is_body_jacobian = true; } + if(task_node["use_local_velocity"] && task_node["use_local_velocity"].as()) + { + _is_velocity_local = true; + } + _otg_maxvel.setConstant(1.0); _otg_maxacc.setConstant(10.0); _trajectory = std::make_shared(); @@ -343,6 +349,17 @@ bool CartesianTaskImpl::setVelocityReference(const Eigen::Vector6d & base_vel_re return true; } +bool CartesianTaskImpl::isVelocityLocal() const +{ + return _is_velocity_local; +} + +void CartesianTaskImpl::setIsVelocityLocal(const bool is_velocity_local) +{ + _is_velocity_local = is_velocity_local; +} + + bool CartesianTaskImpl::setAccelerationReference(const Eigen::Vector6d &base_acc_ref) { if(getActivationState() == ActivationState::Disabled) diff --git a/src/ros/client_api/CartesianRos.cpp b/src/ros/client_api/CartesianRos.cpp index 6f95009..403e51c 100644 --- a/src/ros/client_api/CartesianRos.cpp +++ b/src/ros/client_api/CartesianRos.cpp @@ -7,6 +7,7 @@ #include #include #include +#include using namespace XBot::Cartesian; using namespace XBot::Cartesian::ClientApi; @@ -59,6 +60,8 @@ CartesianRos::CartesianRos(std::string name, _set_safety_lims_cli = _nh.serviceClient(name + "/set_safety_limits"); + _set_is_velocity_local_cli = _nh.serviceClient(name + "/use_local_velocity_reference"); + _task_info_sub = _nh.subscribe(name + "/cartesian_task_properties", 10, &CartesianRos::on_task_info_recv, this); } @@ -80,6 +83,24 @@ bool CartesianRos::isSubtaskLocal() const return get_task_info().use_local_subtasks; } +void CartesianRos::setIsVelocityLocal(const bool is_velocity_local) +{ + std_srvs::SetBool srv; + srv.request.data = is_velocity_local; + if(!_set_is_velocity_local_cli.call(srv)) + { + throw std::runtime_error(fmt::format("Unable to call service '{}'", + _set_is_velocity_local_cli.getService())); + } + + ROS_INFO("%s", srv.response.message.c_str()); +} + +bool CartesianRos::isVelocityLocal() const +{ + return get_task_info().use_local_velocity; +} + void CartesianRos::getVelocityLimits(double & max_vel_lin, double & max_vel_ang) const { @@ -316,6 +337,7 @@ GetCartesianTaskInfoResponse CartesianRos::get_task_info() const res.control_mode = _info.control_mode ; res.state = _info.state ; res.use_local_subtasks = _info.use_local_subtasks; + res.use_local_velocity = _info.use_local_velocity; res.max_vel_lin = _info.max_vel_lin ; res.max_vel_ang = _info.max_vel_ang ; res.max_acc_lin = _info.max_acc_lin ; diff --git a/src/ros/server_api/CartesianRos.cpp b/src/ros/server_api/CartesianRos.cpp index 45b3c7f..29e13ac 100644 --- a/src/ros/server_api/CartesianRos.cpp +++ b/src/ros/server_api/CartesianRos.cpp @@ -87,6 +87,17 @@ CartesianRos::CartesianRos(CartesianTask::Ptr cart_task, _get_info_srv = _ctx->nh().advertiseService(_task->getName() + "/get_cartesian_task_properties", &CartesianRos::get_task_info_cb, this); + _use_local_velocity_reference_srv = _ctx->nh().advertiseService(_task->getName() + "/use_local_velocity_reference", + &CartesianRos::use_local_velocity_reference_cb, this); + +} + +bool CartesianRos::use_local_velocity_reference_cb(std_srvs::SetBoolRequest& req, + std_srvs::SetBoolResponse& res) +{ + _cart->setIsVelocityLocal(req.data); + res.success = true; + return true; } void CartesianRos::run(ros::Time time) @@ -150,6 +161,7 @@ void CartesianRos::publish_task_info() msg.max_vel_lin = srv.response.max_vel_lin; msg.state = srv.response.state; msg.use_local_subtasks = srv.response.use_local_subtasks; + msg.use_local_velocity = srv.response.use_local_velocity; _task_info_pub.publish(msg); @@ -170,14 +182,17 @@ void CartesianRos::online_velocity_reference_cb(geometry_msgs::TwistStampedConst Eigen::Matrix3d b_R_f; b_R_f.setIdentity(); - if(msg->header.frame_id == "world") + if(!_cart->isVelocityLocal()) { - b_R_f = _model->getPose(_cart->getBaseLink()).linear().transpose(); - } - else if(msg->header.frame_id != "") - { - // throws if frame_id does not exist - b_R_f = _model->getPose(msg->header.frame_id, _cart->getBaseLink()).linear(); + if(msg->header.frame_id == "world") + { + b_R_f = _model->getPose(_cart->getBaseLink()).linear().transpose(); + } + else if(msg->header.frame_id != "") + { + // throws if frame_id does not exist + b_R_f = _model->getPose(msg->header.frame_id, _cart->getBaseLink()).linear(); + } } vel.head<3>() = b_R_f * vel.head<3>(); @@ -193,6 +208,7 @@ bool CartesianRos::get_task_info_cb(cartesian_interface::GetCartesianTaskInfoReq res.distal_link = _cart->getDistalLink(); res.control_mode = EnumToString(_cart->getControlMode()); res.use_local_subtasks = _cart->isSubtaskLocal(); + res.use_local_velocity = _cart->isVelocityLocal(); _cart->getVelocityLimits(res.max_vel_lin, res.max_vel_ang); diff --git a/src/rt/CartesianRt.cpp b/src/rt/CartesianRt.cpp index 6f5888a..b9845ad 100644 --- a/src/rt/CartesianRt.cpp +++ b/src/rt/CartesianRt.cpp @@ -50,6 +50,8 @@ void CartesianRt::sendState(bool send) _rt_data._is_body_jacobian = _task_impl->isSubtaskLocal(); + _rt_data._is_velocity_local = _task_impl->isVelocityLocal(); + _to_cli_queue.push(_rt_data); } @@ -62,6 +64,16 @@ bool CartesianRt::isSubtaskLocal() const return _cli_data._is_body_jacobian; } +bool CartesianRt::isVelocityLocal() const +{ + return _cli_data._is_velocity_local; +} + +void CartesianRt::setIsVelocityLocal(const bool is_velocity_local) +{ + _cli_data._is_velocity_local = is_velocity_local; +} + void CartesianRt::getVelocityLimits(double & max_vel_lin, double & max_vel_ang) const { max_vel_lin = _cli_data._max_vel.first; diff --git a/srv/GetCartesianTaskInfo.srv b/srv/GetCartesianTaskInfo.srv index 13ae01c..59778db 100644 --- a/srv/GetCartesianTaskInfo.srv +++ b/srv/GetCartesianTaskInfo.srv @@ -4,6 +4,7 @@ string distal_link string control_mode string state bool use_local_subtasks +bool use_local_velocity float64 max_vel_lin float64 max_vel_ang float64 max_acc_lin