franka_control_node.cpp
Go to the documentation of this file.
1 // Copyright (c) 2017 Franka Emika GmbH
2 // Use of this source code is governed by the Apache-2.0 license, see LICENSE
3 #include <algorithm>
4 #include <atomic>
5 
8 #include <franka/exception.h>
9 #include <franka/robot.h>
10 #include <franka_hw/franka_hw.h>
11 #include <franka_hw/services.h>
12 #include <franka_msgs/ErrorRecoveryAction.h>
13 #include <ros/ros.h>
14 
16 
17 int main(int argc, char** argv) {
18  ros::init(argc, argv, "franka_control_node");
19 
20  ros::NodeHandle public_node_handle;
21  ros::NodeHandle node_handle("~");
22 
24  if (!franka_control.init(public_node_handle, node_handle)) {
25  ROS_ERROR("franka_control_node: Failed to initialize FrankaHW class. Shutting down!");
26  return 1;
27  }
28 
29  franka::Robot& robot = franka_control.robot();
30 
31  std::atomic_bool has_error(false);
32 
33  ServiceContainer services;
34  franka_hw::setupServices(robot, node_handle, services);
35 
37  node_handle, "error_recovery",
38  [&](const franka_msgs::ErrorRecoveryGoalConstPtr&) {
39  try {
40  robot.automaticErrorRecovery();
41  has_error = false;
42  recovery_action_server.setSucceeded();
43  ROS_INFO("Recovered from error");
44  } catch (const franka::Exception& ex) {
45  recovery_action_server.setAborted(franka_msgs::ErrorRecoveryResult(), ex.what());
46  }
47  },
48  false);
49 
50  // Initialize robot state before loading any controller
51  franka_control.update(robot.readOnce());
52 
53  controller_manager::ControllerManager control_manager(&franka_control, public_node_handle);
54 
55  recovery_action_server.start();
56 
57  // Start background threads for message handling
59  spinner.start();
60 
61  while (ros::ok()) {
62  ros::Time last_time = ros::Time::now();
63 
64  // Wait until controller has been activated or error has been recovered
65  while (!franka_control.controllerActive() || has_error) {
66  franka_control.update(robot.readOnce());
67 
68  ros::Time now = ros::Time::now();
69  control_manager.update(now, now - last_time);
70  franka_control.checkJointLimits();
71  last_time = now;
72 
73  if (!ros::ok()) {
74  return 0;
75  }
76  }
77 
78  try {
79  // Run control loop. Will exit if the controller is switched.
80  franka_control.control([&](const ros::Time& now, const ros::Duration& period) {
81  if (period.toSec() == 0.0) {
82  // Reset controllers before starting a motion
83  control_manager.update(now, period, true);
84  franka_control.checkJointLimits();
85  franka_control.reset();
86  } else {
87  control_manager.update(now, period);
88  franka_control.checkJointLimits();
89  franka_control.enforceLimits(period);
90  }
91  return ros::ok();
92  });
93  } catch (const franka::ControlException& e) {
94  ROS_ERROR("%s", e.what());
95  has_error = true;
96  }
97  }
98 
99  return 0;
100 }
virtual void enforceLimits(const ros::Duration &period)
RobotState readOnce()
virtual void reset()
virtual bool controllerActive() const noexcept
virtual void update(const franka::RobotState &robot_state)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
virtual void checkJointLimits()
virtual void control(const std::function< bool(const ros::Time &, const ros::Duration &)> &ros_callback) const
void spinner()
int main(int argc, char **argv)
void setupServices(franka::Robot &robot, ros::NodeHandle &node_handle, ServiceContainer &services)
#define ROS_INFO(...)
ROSCPP_DECL bool ok()
virtual franka::Robot & robot() const
static Time now()
virtual bool init(ros::NodeHandle &root_nh, ros::NodeHandle &robot_hw_nh) override
void update(const ros::Time &time, const ros::Duration &period, bool reset_controllers=false)
void automaticErrorRecovery()
#define ROS_ERROR(...)


franka_control
Author(s): Franka Emika GmbH
autogenerated on Fri Oct 23 2020 03:47:10