4 controller_freq(controller_freq)
30 bool solved_fl, solved_fr, solved_rl, solved_rr;
62 return solved_fl && solved_fr && solved_rl && solved_rr;
69 ROS_WARN(
"UpdateVelocityCommands - Could not calculate inverse kinematics because of singular translation jacobian");
92 ROS_WARN(
"Position setpoint violates joint limits. Command canceled.");
99 sensor_msgs::JointState joint_state_msg;
102 joint_state_msg.header.stamp = ros::Time::now();
105 std_msgs::Float64MultiArray position_commands;
111 joint_state_msg.position = position_commands.data;
142 if(!ros::isInitialized())
151 ros::init_options::NoSigintHandler
158 "/my_robot/controller/shutdown",
164 "/my_robot/controller/ready_to_proceed",
180 "/my_robot/joint_state",
204 "/my_robot/base_pose",
239 for(
int i = 0; i < 12; i++)
274 for(
int i = 0; i < 6; i++)
291 sensor_msgs::JointState joint_state_msg;
293 std_msgs::Float64MultiArray joint_state_position;
294 std_msgs::Float64MultiArray joint_state_velocity;
295 std_msgs::Float64MultiArray joint_state_torque;
297 joint_state_msg.header.stamp = ros::Time::now();
301 tf::matrixEigenToMsg(this->
joint_angles, joint_state_position);
303 tf::matrixEigenToMsg(this->
joint_torques, joint_state_torque);
305 joint_state_msg.position = joint_state_position.data;
306 joint_state_msg.velocity = joint_state_velocity.data;
307 joint_state_msg.effort = joint_state_torque.data;
319 joint_state_msg.position = joint_state_position.data;
320 joint_state_msg.velocity = joint_state_velocity.data;
321 joint_state_msg.effort = joint_state_torque.data;
329 std_msgs::Float64MultiArray base_twist_state_msg;
331 Eigen::Matrix<double, 6, 1> base_twist_state_data = Eigen::Matrix<double, 6, 1>::Zero();
340 tf::matrixEigenToMsg(base_twist_state_data, base_twist_state_msg);
346 std_msgs::Float64MultiArray base_twist_command_msg;
348 Eigen::Matrix<double, 6, 1> base_twist_command_data = Eigen::Matrix<double, 6, 1>::Zero();
350 base_twist_command_data(0) = this->
lin_vel_x;
351 base_twist_command_data(1) = this->
lin_vel_y;
352 base_twist_command_data(5) = this->
ang_vel_z;
354 tf::matrixEigenToMsg(base_twist_command_data, base_twist_command_msg);
360 std_msgs::Float64MultiArray base_pose_msg;
368 std_msgs::Float64MultiArray base_pose_command_msg;
380 ros::Duration(1.0).sleep();
381 ROS_WARN(
"Waiting for initial states");
392 Eigen::Matrix<double, 12, 1> goal_joint_angles = Eigen::Matrix<double, 12, 1>::Zero();
393 goal_joint_angles(0) = M_PI/4.0;
394 goal_joint_angles(3) = - M_PI/4.0;
395 goal_joint_angles(6) = M_PI*3.0/4.0;
396 goal_joint_angles(9) = - M_PI*3.0/4.0;
419 ROS_WARN(
"RunStandUpSequence - Stage 1 Complete");
423 Eigen::Matrix<double, 3, 1> fl_goal_foot_pos;
424 Eigen::Matrix<double, 3, 1> fr_goal_foot_pos;
425 Eigen::Matrix<double, 3, 1> rl_goal_foot_pos;
426 Eigen::Matrix<double, 3, 1> rr_goal_foot_pos;
428 double x_nominal = 0.30;
429 double y_nominal = 0.30;
431 fl_goal_foot_pos(0) = x_nominal;
432 fl_goal_foot_pos(1) = x_nominal;
433 fl_goal_foot_pos(2) = 0.0;
435 fr_goal_foot_pos(0) = x_nominal;
436 fr_goal_foot_pos(1) =-x_nominal;
437 fr_goal_foot_pos(2) = 0.0;
439 rr_goal_foot_pos = - fl_goal_foot_pos;
440 rl_goal_foot_pos = - fr_goal_foot_pos;
442 this->
MoveFeetToPositions(fl_goal_foot_pos, fr_goal_foot_pos, rl_goal_foot_pos, rr_goal_foot_pos);
444 ROS_WARN(
"RunStandUpSequence - Stage 2 Complete");
453 this->
MoveFeetToPositions(fl_goal_foot_pos, fr_goal_foot_pos, rl_goal_foot_pos, rr_goal_foot_pos);
455 ROS_WARN(
"RunStandUpSequence - Stage 3 Complete");
468 ROS_WARN(
"RunStandUpSequence - FL moved successfully");
472 ROS_WARN(
"RunStandUpSequence - FL stance completed");
480 ROS_WARN(
"RunStandUpSequence - RR moved successfully");
484 ROS_WARN(
"RunStandUpSequence - RR stance completed");
492 ROS_WARN(
"RunStandUpSequence - FR moved successfully");
496 ROS_WARN(
"RunStandUpSequence - FR stance completed");
504 ROS_WARN(
"RunStandUpSequence - RL moved successfully");
508 ROS_WARN(
"RunStandUpSequence - RL stance completed");
514 Eigen::Matrix<double, 3, 1> fr_goal_foot_pos,
515 Eigen::Matrix<double, 3, 1> rl_goal_foot_pos,
516 Eigen::Matrix<double, 3, 1> rr_goal_foot_pos)
534 Eigen::Matrix<double, 3, 1> fl_desired_foot_pos;
536 Eigen::Matrix<double, 3, 1> fr_desired_foot_pos;
538 Eigen::Matrix<double, 3, 1> rl_desired_foot_pos;
540 Eigen::Matrix<double, 3, 1> rr_desired_foot_pos;
542 Eigen::Matrix<double, 3, 1> fl_desired_joint_angles;
544 Eigen::Matrix<double, 3, 1> fr_desired_joint_angles;
546 Eigen::Matrix<double, 3, 1> rl_desired_joint_angles;
548 Eigen::Matrix<double, 3, 1> rr_desired_joint_angles;
554 double max_error = 0.0;
558 double fl_foot_pos_error = abs(fl_initial_foot_pos(i) - fl_goal_foot_pos(i));
559 double fr_foot_pos_error = abs(fr_initial_foot_pos(i) - fr_goal_foot_pos(i));
560 double rl_foot_pos_error = abs(rl_initial_foot_pos(i) - rl_goal_foot_pos(i));
561 double rr_foot_pos_error = abs(rr_initial_foot_pos(i) - rr_goal_foot_pos(i));
563 if(fl_foot_pos_error > max_error)
565 max_error = fl_foot_pos_error;
568 if(fr_foot_pos_error > max_error)
570 max_error = fr_foot_pos_error;
573 if(rl_foot_pos_error > max_error)
575 max_error = rl_foot_pos_error;
578 if(rr_foot_pos_error > max_error)
580 max_error = rr_foot_pos_error;
584 double max_velocity = 0.1;
586 double trajectory_duration = max_error / max_velocity;
609 for(
int i = 0; i < number_of_iterations; i++)
614 fl_desired_foot_pos = fl_initial_foot_pos + double(i)/double(number_of_iterations) * (fl_goal_foot_pos - fl_initial_foot_pos);
615 fr_desired_foot_pos = fr_initial_foot_pos + double(i)/double(number_of_iterations) * (fr_goal_foot_pos - fr_initial_foot_pos);
616 rl_desired_foot_pos = rl_initial_foot_pos + double(i)/double(number_of_iterations) * (rl_goal_foot_pos - rl_initial_foot_pos);
617 rr_desired_foot_pos = rr_initial_foot_pos + double(i)/double(number_of_iterations) * (rr_goal_foot_pos - rr_initial_foot_pos);
630 ROS_WARN(
"MoveFeetToPositions - Failed to solve IK for FL");
635 ROS_WARN(
"MoveFeetToPositions - Failed to solve IK for FR");
640 ROS_WARN(
"MoveFeetToPositions - Failed to solve IK for RL");
645 ROS_WARN(
"MoveFeetToPositions - Failed to solve IK for RR");
662 publish_rate.sleep();
672 ROS_WARN(
"MoveJointToSetpoints - Invalid goal joint positions");
676 Eigen::Matrix<double, 12, 1> initial_joint_angles = this->
joint_angles;
678 double max_error = 0.0;
680 for(
int i = 0; i < 12; i++)
682 double error = abs(initial_joint_angles(i) - goal_joint_angles(i));
684 if(error > max_error)
690 double max_angle_rate = 0.3;
692 double trajectory_duration = max_error / max_angle_rate;
698 for(
int i = 0; i < number_of_iterations; i++)
702 joint_angle_commands = initial_joint_angles + double(i)/double(number_of_iterations) * (goal_joint_angles - initial_joint_angles);
706 publish_rate.sleep();
722 Eigen::Matrix<double, 3, 1> initial_foot_position;
726 int joint_index_start;
730 case Kinematics::LegType::frontLeft:
732 ROS_WARN(
"MoveFootToPosition - FL");
735 joint_index_start = 0;
738 case Kinematics::LegType::frontRight:
742 joint_index_start = 3;
745 case Kinematics::LegType::rearLeft:
749 joint_index_start = 6;
752 case Kinematics::LegType::rearRight:
756 joint_index_start = 9;
760 ROS_WARN(
"MoveFootToPosition - Invalid leg chosen");
767 double swing_period = 0.3;
769 double step_height = 0.1;
773 int half_number_of_iterations = number_of_iterations/2;
775 number_of_iterations = half_number_of_iterations * 2;
777 Eigen::Matrix<double, 3, 1> desired_foot_position;
779 Eigen::Matrix<double, 3, 1> desired_joint_angles;
783 for(
int i = 0; i <= number_of_iterations; i++)
788 desired_foot_position = initial_foot_position + double(i)/double(number_of_iterations) * (goal_foot_position - initial_foot_position);
790 if(i <= half_number_of_iterations)
792 desired_foot_position(2) = -
nominal_base_height + step_height * double(i)/double(half_number_of_iterations);
796 desired_foot_position(2) = -
nominal_base_height + step_height * (1.0 - double(i - half_number_of_iterations)/double(half_number_of_iterations));
801 ROS_WARN(
"MoveFootToPosition - Failed to solve IK");
817 publish_rate.sleep();
830 for(
int i = 0; i < number_of_iterations; i++)
838 control_rate.sleep();
843 std_srvs::Empty::Response &_res)
851 std_srvs::Empty::Response &_res)
Eigen::Vector3d fr_offset
bool UpdateJointCommands()
ros::NodeHandlePtr nodeHandle
void TwistCommandCallback(const geometry_msgs::TwistConstPtr &_msg)
Converts twist command messages into desired linear and angular body velocities.
double _ang_vel_x_measured
double _lin_vel_x_estimated
void jointStateCallback(const sensor_msgs::JointStatePtr &msg)
double _lin_vel_y_estimated
Eigen::Vector3d fl_offset
double lin_vel_y
The desired linear robot velocity in the body frame's y direction.
ros::Publisher joint_state_logger
Eigen::Vector3d fl_velocity_body
ros::Subscriber ready_to_proceed_subscriber
void BasePoseStateCallback(const std_msgs::Float64MultiArrayConstPtr &msg)
Eigen::Vector3d rr_offset
bool UpdateVelocityCommands()
ros::Publisher base_twist_state_logger
Eigen::Vector3d rl_position_body
ros::Subscriber twist_command_subscriber
Subscribes to twist command messages from an external controller.
double _ang_vel_y_measured
ros::Subscriber base_pose_state_subscriber
ros::Publisher joint_command_publisher
void StandStill(const double &duration)
Controller(int controller_freq)
bool ReadyToProceed(std_srvs::Empty::Request &_req, std_srvs::Empty::Response &_res)
The ReadyToProceed function handles an incoming readyToProceed service request.
JointState joint_velocity_commands
void WaitForInitialState()
void readyToProceedCallback(const std_msgs::Bool &msg)
Eigen::Matrix< double, 6, 1 > base_pose_commands
Eigen::Vector3d fl_position_body
void TwistStateCallback(const geometry_msgs::TwistConstPtr &_msg)
double _ang_vel_z_estimated
Eigen::Vector3d rr_position_body
double ang_vel_z
The desired angular robot velocity around the robot's z axis.
Eigen::Matrix< double, 6, 1 > base_pose_state
ros::Subscriber twist_state_subscriber
void UpdateFeetPositions()
ros::Publisher joint_command_logger
Eigen::Vector3d fr_position_body
bool MoveFootToPosition(const Kinematics::LegType &leg_type, const Eigen::Matrix< double, 3, 1 > &goal_foot_position)
bool Shutdown(std_srvs::Empty::Request &_req, std_srvs::Empty::Response &_res)
The Shutdown function handles an incoming shutdown service request.
bool MoveFeetToPositions(Eigen::Matrix< double, 3, 1 > fl_goal_foot_pos, Eigen::Matrix< double, 3, 1 > fr_goal_foot_pos, Eigen::Matrix< double, 3, 1 > rl_goal_foot_pos, Eigen::Matrix< double, 3, 1 > rr_goal_foot_pos)
ros::Publisher base_twist_command_logger
double lin_vel_x
The desired linear robot velocity in the body frame's x direction.
ros::Publisher base_pose_state_logger
Eigen::Vector3d rr_velocity_body
Eigen::Vector3d rl_offset
void waitForReadyToProceed()
ros::Subscriber joint_state_subscriber
ros::ServiceServer shutdownService
ROS Shutdown Service.
ros::ServiceServer readyToProceedService
ROS Ready to Proceed Service.
JointState joint_torque_commands
JointState joint_angle_commands
Eigen::Vector3d rl_velocity_body
void SetTwistCommand(double lin_vel_cmd_x, double lin_vel_cmd_y, double ang_vel_cmd_z)
double _lin_vel_z_measured
double nominal_base_height
bool RunStandUpSequence()
bool sendJointPositionCommands()
JointState joint_velocities
bool MoveJointsToSetpoints(Eigen::Matrix< double, 12, 1 > goal_joint_angles)
virtual void setInitialConfiguration()
ros::Publisher base_pose_command_logger
Eigen::Vector3d fr_velocity_body
bool ValidateSolution(const JointSpaceVector &_q_r)
The ValidateSolution function evaluates whether a set of joint angles is within joint limits.
Vector3d SolveSingleLegHipToFootForwardKinematics(const LegType &_leg_type, const Vector3d &_joint_angles)
The SolveSingleLegHipToFootForwardKinematics function calculates the foot position in the hip frame.
Eigen::Matrix< double, 3, 3 > GetTranslationJacobianInB(const LegType &_leg, const BodyType &_body, const double &_theta_hy, const double &_theta_hp, const double &_theta_kp)
The GetTranslationJacobianInB function returns the 3x3 Jacobian matrix for body linear velocities in ...
bool SolveSingleLegInverseKinematics(const bool &_offset, const Vector3d &_h_pos, const Vector3d &_f_pos, Vector3d &_joint_angles)
The SolveSingeLegInverseKinematics function calculates the inverse kinematics for a single leg.
LegType
Leg type enumerator.
#define ACTUATORS_PER_LEG
#define LEG_OFFSET_LENGTH
#define UNINITIALIZED_JOINT_STATE