jog_arm_server.h
Go to the documentation of this file.
1 // Title : jog_arm_server.h
3 // Project : jog_arm
4 // Created : 3/9/2017
5 // Author : Brian O'Neil, Blake Anderson, Andy Zelenak
6 //
7 // BSD 3-Clause License
8 //
9 // Copyright (c) 2018, Los Alamos National Security, LLC
10 // All rights reserved.
11 //
12 // Redistribution and use in source and binary forms, with or without
13 // modification, are permitted provided that the following conditions are met:
14 //
15 // * Redistributions of source code must retain the above copyright notice, this
16 // list of conditions and the following disclaimer.
17 //
18 // * Redistributions in binary form must reproduce the above copyright notice,
19 // this list of conditions and the following disclaimer in the documentation
20 // and/or other materials provided with the distribution.
21 //
22 // * Neither the name of the copyright holder nor the names of its
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 // ARE
30 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
31 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
33 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
34 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
35 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
39 
40 // Server node for arm jogging with MoveIt.
41 
42 #ifndef JOG_ARM_SERVER_H
43 #define JOG_ARM_SERVER_H
44 
45 #include <Eigen/Eigenvalues>
46 #include <jog_msgs/JogJoint.h>
53 #include <sensor_msgs/JointState.h>
54 #include <sensor_msgs/Joy.h>
55 #include <std_msgs/Bool.h>
56 #include <std_msgs/Float64MultiArray.h>
57 #include <tf/transform_listener.h>
58 #include <trajectory_msgs/JointTrajectory.h>
59 
60 namespace jog_arm
61 {
62 // Variables to share between threads, and their mutexes
64 {
65  geometry_msgs::TwistStamped command_deltas;
66  pthread_mutex_t command_deltas_mutex;
67 
68  jog_msgs::JogJoint joint_command_deltas;
69  pthread_mutex_t joint_command_deltas_mutex;
70 
71  sensor_msgs::JointState joints;
72  pthread_mutex_t joints_mutex;
73 
76 
77  // Indicates that an incoming Cartesian command is all zero velocities
80 
81  // Indicates that an incoming joint angle command is all zero velocities
82  bool zero_joint_cmd_flag = true;
83  pthread_mutex_t zero_joint_cmd_flag_mutex;
84 
85  // Indicates that we have not received a new command in some time
86  bool command_is_stale = false;
87  pthread_mutex_t command_is_stale_mutex;
88 
89  // The new trajectory which is calculated
90  trajectory_msgs::JointTrajectory new_traj;
91  pthread_mutex_t new_traj_mutex;
92 
93  // Timestamp of incoming commands
95  pthread_mutex_t incoming_cmd_stamp_mutex;
96 
97  bool ok_to_publish = false;
98  pthread_mutex_t ok_to_publish_mutex;
99 };
100 
101 // ROS params to be read
103 {
104  std::string move_group_name, joint_topic, cartesian_command_in_topic, command_frame, command_out_topic,
105  planning_frame, warning_topic, joint_command_in_topic, command_in_type, command_out_type;
106  double linear_scale, rotational_scale, joint_scale, lower_singularity_threshold, hard_stop_singularity_threshold,
107  lower_collision_proximity_threshold, hard_stop_collision_proximity_threshold, low_pass_filter_coeff,
108  publish_period, publish_delay, incoming_command_timeout, joint_limit_margin, collision_check_rate;
109  bool gazebo, collision_check, publish_joint_positions, publish_joint_velocities, publish_joint_accelerations;
110 };
111 
117 {
118 public:
119  JogROSInterface();
120 
121  // Store the parameters that were read from ROS server
122  static struct jog_arm_parameters ros_parameters_;
123 
124 private:
125  // ROS subscriber callbacks
126  void deltaCartesianCmdCB(const geometry_msgs::TwistStampedConstPtr& msg);
127  void deltaJointCmdCB(const jog_msgs::JogJointConstPtr& msg);
128  void jointsCB(const sensor_msgs::JointStateConstPtr& msg);
129 
130  bool readParameters(ros::NodeHandle& n);
131 
132  // Jogging calculation thread
133  static void* jogCalcThread(void* thread_id);
134 
135  // Collision checking thread
136  static void* CollisionCheckThread(void* thread_id);
137 
138  // Variables to share between threads
139  static struct jog_arm_shared shared_variables_;
140 
141  // static robot_model_loader::RobotModelLoader *model_loader_ptr_;
142  static std::unique_ptr<robot_model_loader::RobotModelLoader> model_loader_ptr_;
143 };
144 
149 {
150 public:
151  explicit LowPassFilter(double low_pass_filter_coeff);
152  double filter(double new_msrmt);
153  void reset(double data);
154  double filter_coeff_ = 10.;
155 
156 private:
157  double prev_msrmts_[3] = { 0., 0., 0. };
158  double prev_filtered_msrmts_[2] = { 0., 0. };
159 };
160 
161 LowPassFilter::LowPassFilter(const double low_pass_filter_coeff)
162 {
163  filter_coeff_ = low_pass_filter_coeff;
164 }
165 
166 void LowPassFilter::reset(const double data)
167 {
168  prev_msrmts_[0] = data;
169  prev_msrmts_[1] = data;
170  prev_msrmts_[2] = data;
171 
172  prev_filtered_msrmts_[0] = data;
173  prev_filtered_msrmts_[1] = data;
174 }
175 
176 double LowPassFilter::filter(const double new_msrmt)
177 {
178  // Push in the new measurement
179  prev_msrmts_[2] = prev_msrmts_[1];
180  prev_msrmts_[1] = prev_msrmts_[0];
181  prev_msrmts_[0] = new_msrmt;
182 
183  double new_filtered_msrmt = (1 / (1 + filter_coeff_ * filter_coeff_ + 1.414 * filter_coeff_)) *
184  (prev_msrmts_[2] + 2 * prev_msrmts_[1] + prev_msrmts_[0] -
185  (filter_coeff_ * filter_coeff_ - 1.414 * filter_coeff_ + 1) * prev_filtered_msrmts_[1] -
186  (-2 * filter_coeff_ * filter_coeff_ + 2) * prev_filtered_msrmts_[0]);
187 
188  // Store the new filtered measurement
189  prev_filtered_msrmts_[1] = prev_filtered_msrmts_[0];
190  prev_filtered_msrmts_[0] = new_filtered_msrmt;
191 
192  return new_filtered_msrmt;
193 }
194 
198 class JogCalcs
199 {
200 public:
201  JogCalcs(const jog_arm_parameters& parameters, jog_arm_shared& shared_variables,
202  const std::unique_ptr<robot_model_loader::RobotModelLoader>& model_loader_ptr);
203 
204 protected:
206 
208 
209  sensor_msgs::JointState incoming_jts_;
210 
211  bool cartesianJogCalcs(const geometry_msgs::TwistStamped& cmd, jog_arm_shared& shared_variables);
212 
213  bool jointJogCalcs(const jog_msgs::JogJoint& cmd, jog_arm_shared& shared_variables);
214 
215  // Parse the incoming joint msg for the joints of our MoveGroup
216  bool updateJoints();
217 
218  Eigen::VectorXd scaleCartesianCommand(const geometry_msgs::TwistStamped& command) const;
219 
220  Eigen::VectorXd scaleJointCommand(const jog_msgs::JogJoint& command) const;
221 
222  Eigen::MatrixXd pseudoInverse(const Eigen::MatrixXd& J) const;
223 
224  // This pseudoinverse calculation is more stable near stabilities. See Golub, 1965, "Calculating the Singular Values..."
225  Eigen::MatrixXd pseudoInverse(const Eigen::MatrixXd& u_matrix, const Eigen::MatrixXd& v_matrix, const Eigen::MatrixXd& s_diagonals) const;
226 
227  void enforceJointVelocityLimits(Eigen::VectorXd& calculated_joint_vel);
228  bool addJointIncrements(sensor_msgs::JointState& output, const Eigen::VectorXd& increments) const;
229 
230  // Reset the data stored in low-pass filters so the trajectory won't jump when
231  // jogging is resumed.
232  void resetVelocityFilters();
233 
234  // Avoid a singularity or other issue.
235  // Needs to be handled differently for position vs. velocity control
236  void halt(trajectory_msgs::JointTrajectory& jt_traj);
237 
238  void publishWarning(bool active) const;
239 
240  bool checkIfJointsWithinBounds(trajectory_msgs::JointTrajectory_<std::allocator<void>>& new_jt_traj);
241 
242  // Possibly calculate a velocity scaling factor, due to proximity of
243  // singularity and direction of motion
244  double decelerateForSingularity(Eigen::MatrixXd jacobian, const Eigen::VectorXd commanded_velocity);
245 
246  // Apply velocity scaling for proximity of collisions and singularities
247  bool applyVelocityScaling(jog_arm_shared& shared_variables, trajectory_msgs::JointTrajectory& new_jt_traj,
248  const Eigen::VectorXd& delta_theta, double singularity_scale);
249 
250  trajectory_msgs::JointTrajectory composeOutgoingMessage(sensor_msgs::JointState& joint_state,
251  const ros::Time& stamp) const;
252 
253  void lowPassFilterVelocities(const Eigen::VectorXd& joint_vel);
254 
255  void lowPassFilterPositions();
256 
257  void insertRedundantPointsIntoTrajectory(trajectory_msgs::JointTrajectory& trajectory, int count) const;
258 
259  const robot_state::JointModelGroup* joint_model_group_;
260 
261  robot_state::RobotStatePtr kinematic_state_;
262 
263  sensor_msgs::JointState jt_state_, original_jts_;
264  trajectory_msgs::JointTrajectory new_traj_;
265 
267 
268  std::vector<jog_arm::LowPassFilter> velocity_filters_;
269  std::vector<jog_arm::LowPassFilter> position_filters_;
270 
272 
274 };
275 
277 {
278 public:
279  CollisionCheckThread(const jog_arm_parameters& parameters, jog_arm_shared& shared_variables,
280  const std::unique_ptr<robot_model_loader::RobotModelLoader>& model_loader_ptr);
281 };
282 
283 } // namespace jog_arm
284 
285 #endif // JOG_ARM_SERVER_H
tf::TransformListener listener_
double filter(double new_msrmt)
pthread_mutex_t collision_velocity_scale_mutex
sensor_msgs::JointState incoming_jts_
pthread_mutex_t zero_joint_cmd_flag_mutex
ros::NodeHandle nh_
std::vector< jog_arm::LowPassFilter > position_filters_
pthread_mutex_t incoming_cmd_stamp_mutex
trajectory_msgs::JointTrajectory new_traj_
data
pthread_mutex_t new_traj_mutex
geometry_msgs::TwistStamped command_deltas
pthread_mutex_t joint_command_deltas_mutex
jog_msgs::JogJoint joint_command_deltas
ros::Publisher warning_pub_
jog_arm_parameters parameters_
sensor_msgs::JointState joints
static std::unique_ptr< robot_model_loader::RobotModelLoader > model_loader_ptr_
moveit::planning_interface::MoveGroupInterface move_group_
pthread_mutex_t zero_cartesian_cmd_flag_mutex
pthread_mutex_t command_is_stale_mutex
std::vector< jog_arm::LowPassFilter > velocity_filters_
pthread_mutex_t joints_mutex
trajectory_msgs::JointTrajectory new_traj
LowPassFilter(double low_pass_filter_coeff)
const robot_state::JointModelGroup * joint_model_group_
sensor_msgs::JointState original_jts_
pthread_mutex_t ok_to_publish_mutex
void reset(double data)
robot_state::RobotStatePtr kinematic_state_
pthread_mutex_t command_deltas_mutex


jog_arm
Author(s): Brian O'Neil, Andy Zelenak , Blake Anderson, Nitish Sharma, Alexander Rössler
autogenerated on Mon Jun 10 2019 13:47:53