目录
导航在这里:白泽四足机器人导航贴
源码:
整体项目文件地址:
先看效果:
白泽四足机器人ROS+rviz前进行走
#include
#include
#include
#include "ros/ros.h"
#include "sensor_msgs/JointState.h"
#include "turtlesim/Pose.h"
#include "tf2_ros/static_transform_broadcaster.h"
#include "tf2_ros/transform_broadcaster.h"
#include "geometry_msgs/TransformStamped.h"
#include "tf2/LinearMath/Quaternion.h"
#include "kdl_parser/kdl_parser.hpp"
#include "kdl/chainiksolverpos_nr_jl.hpp"
#include "trac_ik/trac_ik.hpp"
#include "urdf/model.h"
#include
#define pi 3.141592653
int main(int argc,char* argv[])
{
setlocale(LC_ALL,"");
ros::init(argc,argv,"gou2_test");
ros::NodeHandle nh;
ros::Publisher joint_pub=nh.advertise("joint_states",1);
//定义tf坐标广播器
tf2_ros::StaticTransformBroadcaster broadcaster;
geometry_msgs::TransformStamped ts;
sensor_msgs::JointState joint_state;
std::string robot_desc_string;
nh.param("robot_description", robot_desc_string, std::string());
KDL::Tree my_tree;
if(!kdl_parser::treeFromString(robot_desc_string, my_tree))
//if(!kdl_parser::treeFromFile("/home/zhitong/catkin_ws_serial/src/Gou2/urdf/Gou2.urdf", my_tree))
{
ROS_ERROR("Failed to construct kdl tree");
}
else
{
ROS_INFO("成功生成kdl树!");
}
std::vector joint_name = {
"LF_JIAN_JOINT", "LF_ZHOU_JOINT", "LF_XI_JOINT", "LF_R_JOINT","LF_P_JOINT", "LF_Y_JOINT",
"LB_JIAN_JOINT", "LB_ZHOU_JOINT", "LB_XI_JOINT", "LB_R_JOINT","LB_P_JOINT", "LB_Y_JOINT",
"RF_JIAN_JOINT", "RF_ZHOU_JOINT", "RF_XI_JOINT", "RF_R_JOINT","RF_P_JOINT", "RF_Y_JOINT",
"RB_JIAN_JOINT", "RB_ZHOU_JOINT", "RB_XI_JOINT", "RB_R_JOINT","RB_P_JOINT", "RB_Y_JOINT"
};
std::vector joint_pos = {
0,0,0,0,0,0,0,
0,0,0,0,0,0,0,
0,0,0,0,0,0,0,
0,0,0,0,0,0,0
};
std::string urdf_param = "/robot_description";
double timeout = 0.005;
double eps = 1e-5;
std::string chain_start = "base_link";
std::string chain_end = "LF_Y_LINK";
TRAC_IK::TRAC_IK tracik_solver(chain_start, chain_end, urdf_param, timeout, eps);
KDL::Chain chain;
KDL::JntArray ll, ul; //关节下限, 关节上限
bool valid = tracik_solver.getKDLChain(chain);
if(!valid)
{
ROS_ERROR("There was no valid KDL chain found");
}
valid = tracik_solver.getKDLLimits(ll, ul);
if(!valid)
{
ROS_ERROR("There was no valid KDL joint limits found");
}
KDL::ChainFkSolverPos_recursive fk_solver(chain);
ROS_INFO("关节数量: %d", chain.getNrOfJoints());
KDL::JntArray q(6); // 初始关节位置
q(0)=0;
q(1)=-pi/6;
q(2)=pi/6;
q(3)=0;
q(4)=0;
q(5)=0;
//定义末端4x4齐次变换矩阵(各个关节位于初始位置时,末端齐次矩阵)
KDL::Frame end_effector_pose1_l;
KDL::Frame end_effector_pose1_r;
//定义末端4x4齐次变换矩阵(各个关节的实时末端齐次矩阵)
KDL::Frame end_effector_pose_l;//left now
KDL::Frame end_effector_pose_r;//left now
//定义逆运动学解算结果存储数组
KDL::JntArray result_l;//left
KDL::JntArray result_r;//right
//上一帧的关节变量
KDL::JntArray resu_last_l;//left last
KDL::JntArray resu_last_r;//right last
ros::Rate r(5);
auto print_frame_lambda = [](KDL::Frame f)
{
double x, y, z, roll, pitch, yaw;
x = f.p.x();
y = f.p.y();
z = f.p.z();
f.M.GetRPY(roll, pitch, yaw);
std::cout << "x:" << x << " y:" << y << " z:" << z << " roll:" << roll << " pitch:" << pitch << " yaw:" << yaw << std::endl;
};
//正运动学求初始状态齐次变换矩阵
fk_solver.JntToCart(q,end_effector_pose1_l);
fk_solver.JntToCart(q,end_effector_pose1_r);
ROS_INFO("更新关节状态");
joint_state.header.stamp = ros::Time::now();
//ROS_INFO("%d",joint_state.header.stamp);
joint_state.name.resize(24);
joint_state.position.resize(24);
for(size_t i=0;i<=23;i++)
{
joint_state.name[i] = joint_name[i];
}
for(int i=0;i<=23;i++)
{
joint_state.position[i]=q(i%6);
}
joint_pub.publish(joint_state);
fk_solver.JntToCart(q, end_effector_pose_l);
fk_solver.JntToCart(q, end_effector_pose_r);
resu_last_l=q;
resu_last_r=q;
while(ros::ok())
{
//x=0.02*(t-sint);
//y=0.02*(1-cost);
for(int i=1;i<=20;i++)
{
double t=2*pi*i/20;
double x=0.005*(t-sin(t));
double z=0.005*(1-cos(t));
end_effector_pose_l.p.data[0]=end_effector_pose1_l.p.data[0]+x;
end_effector_pose_l.p.data[2]=end_effector_pose1_l.p.data[2]+z;
int rc_l = tracik_solver.CartToJnt(resu_last_l, end_effector_pose_l, result_l);
end_effector_pose_r.p.data[0]=end_effector_pose1_r.p.data[0]+0.005*2*pi-x;
end_effector_pose_r.p.data[2]=end_effector_pose1_r.p.data[2];
int rc_r = tracik_solver.CartToJnt(resu_last_r, end_effector_pose_r, result_r);
joint_state.header.stamp = ros::Time::now();
for(int j=0;j<=5;j++)
{
joint_state.position[j]=result_l(j);
}
for(int j=6;j<=17;j++)
{
joint_state.position[j]=result_r(j%6);
}
for(int j=18;j<=23;j++)
{
joint_state.position[j]=result_l(j%6);
}
/*
for(int j=0;j<=23;j++)
{
joint_state.position[j]=((j/6)==(0||3))?result_l(j%6):result_r(j%6);
}
*/
joint_pub.publish(joint_state);
resu_last_l=result_l;
resu_last_r=result_r;
r.sleep();
}
for(int i=1;i<=20;i++)
{
double t=2*pi*i/20;
double x=0.005*(t-sin(t));
double z=0.005*(1-cos(t));
end_effector_pose_l.p.data[0]=end_effector_pose1_l.p.data[0]+0.005*2*pi-x;
end_effector_pose_l.p.data[2]=end_effector_pose1_l.p.data[2];
int rc_l = tracik_solver.CartToJnt(resu_last_l, end_effector_pose_l, result_l);
end_effector_pose_r.p.data[0]=end_effector_pose1_r.p.data[0]+x;
end_effector_pose_r.p.data[2]=end_effector_pose1_r.p.data[2]+z;
int rc_r = tracik_solver.CartToJnt(resu_last_r, end_effector_pose_r, result_r);
joint_state.header.stamp = ros::Time::now();
for(int j=0;j<=5;j++)
{
joint_state.position[j]=result_l(j);
}
for(int j=6;j<=17;j++)
{
joint_state.position[j]=result_r(j%6);
}
for(int j=18;j<=23;j++)
{
joint_state.position[j]=result_l(j%6);
}
/*
for(int j=0;j<=23;j++)
{
joint_state.position[j]=((j/6)==(0||3))?result_l(j%6):result_r(j%6);
}
*/
joint_pub.publish(joint_state);
resu_last_l=result_l;
resu_last_r=result_r;
r.sleep();
}
}
return 0;
}
https://gitee.com/li9535/arduino-baize-quadruped-robot/tree/master/Gou2