45 double k_torque = 50.0;
57 double k_p_hy = 100.0;
58 double k_p_hp = 100.0;
59 double k_p_kp = 100.0;
66 this->
K_p(0, 0) = k_p_hy;
67 this->
K_p(1, 1) = k_p_hp;
68 this->
K_p(2, 2) = k_p_kp;
70 this->
K_d(0, 0) = k_d_hy;
71 this->
K_d(1, 1) = k_d_hp;
72 this->
K_d(2, 2) = k_d_kp;
75 double k_pos_error_vel_control_hy = 25.0;
76 double k_pos_error_vel_control_hp = 25.0;
77 double k_pos_error_vel_control_kp = 25.0;
103 if(!ros::isInitialized())
111 "single_leg_controller_node",
112 ros::init_options::NoSigintHandler
117 this->
node_handle.reset(
new ros::NodeHandle(
"single_leg_controller_node"));
122 "/my_robot/gen_coord",
139 "/my_robot/joint_forces",
166 "/controller/joint_setpoints",
175 "/motor/confirmation",
247 for(
int i = 0; i < 3; i++)
266 double c = _max_swing_height;
267 double a =
c/pow(0.5, 4.0);
268 double b = -2.0*
a*pow(0.5, 2.0);
271 Eigen::Matrix<double, 3, 1> trajectory;
274 double x = _percentage - 0.5;
277 trajectory(0) =
a*pow(
x, 4.0) +
b*pow(
x, 2.0) +
c - _hip_height;
280 trajectory(1) = (4.0*
a*pow(
x, 3.0) + 2.0*
b*
x)/_period;
283 trajectory(2) = (12.0*
a*pow(
x, 2.0) + 2.0*
b)/pow(_period, 2.0);
291 const double &_percentage,
292 const double &_period,
293 const double &_max_travel,
300 double a = 30.0*_max_travel;
301 double b = -15.0*_max_travel;
302 double c = 1.875*_max_travel;
303 double d = -_max_travel*7.0/16.0;
306 _axis_pos = 0.2*
a*pow((_percentage - 0.5), 5.0) +
b*pow((_percentage - 0.5), 3.0)/3.0 +
c*_percentage + d;
309 _axis_vel = (
a*pow((_percentage - 0.5), 4.0) +
b*pow((_percentage - 0.5), 2.0) +
c)/_period;
312 _axis_acc = (4.0*
a*pow((_percentage - 0.5), 3.0) + 2.0*
b*(_percentage - 0.5))/(_period*_period);
433 ROS_WARN(
"[setFootPose] Failed to solve inverse kinematics");
441 double max_joint_error = 0.0;
452 double a = 30.0 * max_joint_error;
453 double b = -15.0 * max_joint_error;
454 double c = 1.875 * max_joint_error;
455 double d = - max_joint_error * 7.0/16.0;
456 double _percentage = 0.5;
505 ROS_INFO(
"P: %f\thy_pos: %f\thp_pos: %f\tkp_pos: %f", progress, hy_pos, hp_pos, kp_pos);
530 ROS_WARN(
"[updateJointReferences] Failed to solve inverse kinematics");
561 const Eigen::Matrix<double, 3, 1> &_joint_pos_ref,
562 const Eigen::Matrix<double, 3, 1> &_joint_vel_ref,
563 const Eigen::Matrix<double, 3, 1> &_joint_acc_ref,
564 const Eigen::Matrix<double, 3, 1> &_joint_pos,
565 const Eigen::Matrix<double, 3, 1> &_joint_vel
569 Eigen::Matrix<double, 3, 1> normalized_joint_torques = _joint_acc_ref -
K_p*(_joint_pos - _joint_pos_ref) -
K_d*(_joint_vel - _joint_vel_ref);
607 ROS_WARN(
"Position setpoint violates joint limits. Command canceled.");
612 sensor_msgs::JointState joint_state_msg;
615 joint_state_msg.header.stamp = ros::Time::now();
618 joint_state_msg.name.push_back(
"position");
621 std_msgs::Float64MultiArray position_commands;
624 tf::matrixEigenToMsg(this->
joint_pos_ref, position_commands);
627 joint_state_msg.position = position_commands.data;
637 sensor_msgs::JointState joint_state_msg;
640 joint_state_msg.header.stamp = ros::Time::now();
643 joint_state_msg.name.push_back(
"velocity");
646 std_msgs::Float64MultiArray joint_vel_command_array;
652 joint_state_msg.effort = joint_vel_command_array.data;
661 sensor_msgs::JointState joint_state_msg;
664 joint_state_msg.header.stamp = ros::Time::now();
667 joint_state_msg.name.push_back(
"torque");
670 std_msgs::Float64MultiArray joint_torque_command_array;
676 joint_state_msg.effort = joint_torque_command_array.data;
685 Eigen::Matrix<double, 3, 1> trajectory_initial_joint_pos =
joint_pos;
688 Eigen::Matrix<double, 3, 1> trajectory_goal_joint_pos;
693 ROS_WARN(
"In the function SingleLegController::moveFootToPosition the inverse kinematics solver failed to find a valid solution.");
700 ROS_WARN(
"In the function SingleLegController::moveFootToPosition the goal joint angles violated the angle constaints of the leg.");
708 double max_joint_error = 0.0;
712 if(abs(trajectory_goal_joint_pos(i) - trajectory_initial_joint_pos(i)) > max_joint_error)
714 max_joint_error = abs(trajectory_goal_joint_pos(i) - trajectory_initial_joint_pos(i));
722 double trajectory_duration = max_joint_error/max_joint_velocity;
728 double _iteration = 0.0;
734 this->
joint_pos_ref = trajectory_initial_joint_pos + (trajectory_goal_joint_pos - trajectory_initial_joint_pos)*_iteration/_final_iteration;
738 command_send_rate.sleep();
740 if(_iteration <= _final_iteration)
745 ROS_INFO(
"Trying to get to final position. I: %f\tI_f: %f", _iteration, _final_iteration);
838 ROS_INFO(
"Target Reached");
843 ROS_INFO(
"Error too large");
852 ROS_INFO(
"Velocity is small");
857 ROS_INFO(
"Velocity is too large");
882 ROS_INFO(
"Pos: %f, %f, %f\tVel: %f, %f, %f\tAcc: %f, %f, %f", this->
foot_pos_ref(0), this->
foot_pos_ref(1), this->
foot_pos_ref(2), this->
foot_vel_ref(0), this->
foot_vel_ref(1), this->
foot_vel_ref(2), this->
foot_acc_ref(0), this->
foot_acc_ref(1), this->
foot_acc_ref(2));
887 ROS_INFO(
"joint_pos_ref: %f, %f, %f\tq_d_ref: %f, %f, %f\tq_dd_ref: %f, %f, %f", this->
joint_pos_ref(0), this->
joint_pos_ref(1), this->
joint_pos_ref(2), this->
joint_vel_ref(0), this->
joint_vel_ref(1), this->
joint_vel_ref(2), this->
joint_acc_ref(0), this->
joint_acc_ref(1), this->
joint_acc_ref(2));
892 ROS_INFO(
"I: %.0f\tP: %.3f, %.3f, %.3f\tV: %.3f, %.3f, %.3f\tA: %.3f, %.3f, %.3f\tq_r: %.3f, %.3f, %.3f\tq_d_r: %.3f, %.3f, %.3f\tq_dd_r: %.3f, %.3f, %.3f\tq: %.3f, %.3f, %.3f\tq_d: %.3f, %.3f, %.3f\tT: %.3f, %.3f, %.3f",
927 ros::Rate set_gains_rate(0.4);
933 std_msgs::Float64MultiArray motor_gain_msg;
966 ROS_INFO(
"Waiting for gains set confirmation message");
969 set_gains_rate.sleep();
976 ROS_INFO(
"Gains set sucessfully");
bool ValidateSolution(const JointSpaceVector &_q_r)
The ValidateSolution function evaluates whether a set of joint angles is within joint limits.
Eigen::Matrix< double, 3, 3 > GetSingleLegMassMatrix(const Eigen::Matrix< double, 3, 1 > &_q)
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 ...
Eigen::Matrix< double, 3, 1 > GetSingleLegCoriolisAndCentrifugalTerms(const Eigen::Matrix< double, 3, 1 > &_q, const Eigen::Matrix< double, 3, 1 > &_u)
Eigen::Matrix< double, 3, 3 > GetTranslationJacobianInBDiff(const LegType &_leg, const BodyType &_body, const double &_theta_hy, const double &_theta_hp, const double &_theta_kp, const double &_dot_theta_hy, const double &_dot_theta_hp, const double &_dot_theta_kp)
The GetTranslationJacobianDerivativeInB function returns the time derivative of the 3x3 translation J...
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.
Eigen::Matrix< double, 3, 1 > GetSingleLegGravitationalTerms(const Eigen::Matrix< double, 3, 1 > &_q)
const int NUMBER_OF_MOTORS
The number of motors used in single leg control tests.
Eigen::Matrix< double, 3, 1 > foot_pos_goal
When using setpointTrajectory control these are the joint angles we want to reach eventually.
double k_p_torque_kp
Knee pitch motor torque control proportional gain.
ros::Subscriber motor_confirmation_subscriber
Subscribes to confirmation messages from the motor.
double max_swing_height
The maximum height above the ground to lift the foot.
void writeToLog()
Write the joint references and estimated states to the log.
ros::Subscriber generalized_forces_subscriber
Subscribes to generalized forces messages.
std::unique_ptr< ros::NodeHandle > node_handle
ROS node handle.
double k_i_torque_hp
Hip pitch motor torque control integral gain.
void jointSetpointCallback(const std_msgs::Float64MultiArrayConstPtr &_msg)
Listens to joint setpoints messages.
double max_pose_vel
Max pose control joint angle velocity [rad/s].
Eigen::Matrix< double, 3, 1 > joint_torque_ref
The reference joint torques for the motors.
void updateJointVelocityCommands()
Updates the joint velocity control commands based on the joint velocity reference and the joint posit...
Eigen::Matrix< double, 3, 1 > joint_vel_ref
The reference joint velocities for the motors.
void setMotorGains()
Tries to set the control gains in the motors. The function loops until it succeeds.
double k_p_torque_hp
Hip pitch motor torque control proportional gain.
void printJointTrajectories()
Print the joint trajectory references.
double k_p_torque_hy
Hip yaw motor torque control proportional gain.
ros::Publisher log_joint_references_publisher
Publishes joint position references for logging.
void printAllStates()
Print various information about all joints.
double publish_frequency
The expected publish frequency of the robot. This is used to calculate the maximum number of iteratio...
void updateFootTrajectoryReference()
Update the foot trajectory based on the leg state.
const double POSITION_CONVERGENCE_CRITERIA
Convergence crieria for position control test.
Eigen::Matrix< double, 3, 1 > foot_acc_ref
The foot acceleration reference relative to the hip.
double k_p_vel_hy
Hip yaw joint motor velocity control proportional gain.
void updateClosedLoopTorqueCommands()
A non model based torque controller.
void printSpatialTrajectories()
Print the foot trajectory reference.
Eigen::Matrix< double, 3, 1 > joint_torque
The estimated joint torques of the motors.
Eigen::Matrix< double, 3, 1 > joint_pos_goal
The joint angles we want to eventually reach when using pose trajectory control.
Eigen::Matrix< double, 3, 1 > joint_torque_commands
The joint torque command being sent to the motors.
double k_i_vel_hp
Hip pitch joint motor velocity control integral gain.
double k_i_vel_hy
Hip yaw joint motor velocity control integral gain.
double k_i_torque_kp
Knee pitch motor torque control integral gain.
double final_pose_iteration
The final iteration used for pose control.
bool moveFootToNominalPosition()
The function tries to move the foot to the nominal trajectory position.
Eigen::Matrix< double, 3, 1 > joint_pos
The estimated joint angles of the motors.
Eigen::Matrix< double, 3, 1 > joint_acc_ref
The reference joint accelerations for the motors.
ros::Subscriber ready_to_proceed_subscriber
Subscribes to messages deciding whether or not we should proceed in the script.
void updateStanceFootPositionTrajectory()
Update the stance foot tractory for the leg.
ros::Publisher log_joint_states_publisher
Publishes joint positions for logging.
Eigen::Matrix< double, 3, 1 > joint_pos_ref
The reference joint angles for the motors.
double k_p_vel_hp
Hip pitch joint motor velocity control proportional gain.
ros::Subscriber generalized_velocities_subscriber
Subscribes to generalized velocities messages.
ros::Publisher joint_state_publisher
Publishes velocity commands to the teensy to control the motors.
Kinematics kinematics
Kinematics object.
void printTorqueReferences()
Print the joint torque references.
ros::Subscriber generalized_coordinates_subscriber
Subscribes to generalized coordinates messages.
double k_p_pos_kp
Knee pitch joint motor position control proportional gain.
void generalizedForcesCallback(const std_msgs::Float64MultiArrayConstPtr &_msg)
Listens to joint force messages from the simulated leg.
double phase_period
The duration of a phase period in seconds.
bool gains_set
Keeps track of whether or not the motor gains have been set.
double k_p_vel_kp
Knee pitch joint motor velocity control proportional gain.
ros::Subscriber joint_setpoint_subscriber
Subscribes to joint setpoint messages.
Eigen::Matrix< double, 3, 3 > K_d
A diagonal matrix of derivative gains for the closed loop torque controller.
Eigen::Matrix< double, 3, 1 > joint_vel
The estimated joint velocities of the motors.
void jointStateCallback(const sensor_msgs::JointStatePtr &_msg)
Listens to joint state messages from the motors The messages contains joint angles,...
Eigen::Matrix< double, 3, 1 > foot_pos_ref
The foot position reference relative to the hip.
void initROS()
This function initilizes ROS.
SingleLegController(double _publish_frequency)
Constructor.
void sendJointVelocityCommands()
Updates the joint velocity commands and send them to the motors.
void sendJointPositionCommands()
Sends a joint position commands to the motors.
double x_step_distance
The step distance in the x direction.
bool updatePoseControlJointTrajectoryReference()
Update the pose control trajectory reference for the single leg.
bool isInitialStateReceived()
Check if the uninitalized joint state of the robot has been overridden by measurements.
double current_pose_iteration
The current iteration used for pose control.
double k_p_pos_hp
Hip pitch joint motor position control proportional gain.
double hip_height
The standard height of the hips above the ground.
Eigen::Matrix< double, 3, 1 > calculateSwingLegHeightTrajectory(double _percentage, double _period, double _max_swing_height, double _hip_height)
This function calculates the swing leg height trajectory based on various gait cycle parameters.
void motorConfirmationCallback(const std_msgs::Bool &_msg)
Listens to a confirmation message from the motors which is used to indicate if the motor gains have b...
double final_iteration
The final iteration of a gait phase.
bool isJointVelocitySmall()
Checks if the sum of squared joint velocities are smaller than a certain threshold.
void updateSwingFootPositionTrajectory()
Update the swing foot trajectory for the leg.
void setPoseGoal(Eigen::Matrix< double, 3, 1 > _foot_pos)
Set the final and initial states for pose control trajectories.
double y_step_distance
The step distance in the y direction.
sensor_msgs::JointState joint_state_log_msg
The joint state message that is used to log states.
double k_i_pos_hy
Hip yaw joint motor position control integral gain.
double k_i_torque_hy
Hip yaw motor torque control integral gain.
Eigen::Matrix< double, 3, 1 > foot_vel_ref
The foot velocity reference relative to the hip.
void updateJointReferences()
Update The joint trajectory reference based on the spatial foot trajectory.
ros::Subscriber joint_state_subscriber
Subscribes to joint state messages from the motors.
double current_iteration
The current iteration in a gait phase. This should be incremented for every control loop.
void generalizedVelocitiesCallback(const std_msgs::Float64MultiArrayConstPtr &_msg)
Listens to joint velocity messages from the simulated leg.
Eigen::Matrix< double, 3, 3 > K_p
A diagonal matrix of proportional gains for the closed loop torque controller.
ros::Publisher motor_gain_publisher
Publishes desired motor gains to the motors.
bool moveJointsToSetpoints()
The function tries to move the foot to the foot position given by the input parameters.
Eigen::Matrix< double, 3, 1 > joint_pos_initial
The joint angles at the beginning of a trajectory.
bool ready_to_proceed
A variable used to control the flow of the program. It can be set throuh a boolean message received b...
sensor_msgs::JointState joint_reference_log_msg
The joint state message that is used to log references.
bool updateGaitPhase()
Increments the gait cycle iterator and updates the leg state.
bool moveFootToPosition(Eigen::Matrix< double, 3, 1 > _foot_goal_pos)
Creates a trajectory from the current foot position to the goal foot position and moves the foot to t...
void increaseIterator()
Increment the gait cycle iterator. It stops iterating when the final iteration is reached.
double k_p_pos_hy
Hip yaw joint motor position control proportional gain.
void readyToProceedCallback(const std_msgs::Bool &_msg)
The ready_to_proceed parameter is changed based on the incomming message.
void sendJointTorqueCommands()
Updates the joint torque control commands based on the desired foot position.
void checkForNewMessages()
Function used to check if any new ROS messages has been received.
void updateJointTorqueCommands()
Overloaded function that uses the current joint references and joint states.
double y_nominal
The nominal y position of the foot relative to the hip.
void generalizedCoordinatesCallback(const std_msgs::Float64MultiArrayConstPtr &_msg)
Listens to joint angle messages from the simulated leg.
double pose_period
The time used to change from one pose to the next.
bool isTargetPositionReached()
Check if the squared error between the current joint angles and target joint angles is smaller than s...
double k_i_pos_kp
Knee pitch joint motor position control integral gain.
const double UNINITIALIZED_STATE
The value of an uninitialized state.
Eigen::Matrix< double, 3, 1 > joint_vel_commands
The velocity commands sent to the motors.
Eigen::Matrix< double, 3, 3 > K_pos_error_vel_control
A digonal matrix for of gains used for the position error in the closed loop velocity controller.
double k_i_pos_hp
Hip pitch joint motor position control integral gain.
GaitPhase gait_phase
The current gait phase of the leg.
void calculateSingleAxisTrajectory(const double &_percentage, const double &_period, const double &_max_travel, double &_axis_pos, double &_axis_vel, double &_axis_acc)
This functions calculates a smooth trajectory along a single linear axis. Please see the report for d...
double x_nominal
The nominal x position of the foot relative to the hip.
double degToRad(const double &_deg)
The degToRad function converts degrees to radians.
double radToDeg(const double &_rad)
The radToDeg function converts radians to degrees.