算法开发调试过程中的tips(持续更新)

tip_1.根据两位姿,计算线加速度和角速度的代码表达(from cartographer)

const transform::Rigid3d& newest_pose = newest_timed_pose.pose;
const transform::Rigid3d& oldest_pose = oldest_timed_pose.pose;
linear_velocity_from_poses_ =(newest_pose.translation() - oldest_pose.translation()) / queue_delta;//线速度
angular_velocity_from_poses_=transform::RotationQuaternionToAngleAxisVector(oldest_pose.rotation().inverse() * newest_pose.rotation()) /queue_delta;//角速度

这里需要注意的是旋转增量计算方法(相对旋转用四元数乘法)

template <typename T>
Eigen::Matrix<T, 3, 1> RotationQuaternionToAngleAxisVector(const Eigen::Quaternion<T>& quaternion) 
{
  Eigen::Quaternion<T> normalized_quaternion = quaternion.normalized();
  // We choose the quaternion with positive 'w', i.e., the one with a smaller
  // angle that represents this orientation.
  if (normalized_quaternion.w() < 0.) 
  {
    normalized_quaternion.w() = -1. * normalized_quaternion.w();
    normalized_quaternion.x() = -1. * normalized_quaternion.x();
    normalized_quaternion.y() = -1. * normalized_quaternion.y();
    normalized_quaternion.z() = -1. * normalized_quaternion.z();
  }
  // We convert the normalized_quaternion into a vector along the rotation axis
  // with length of the rotation angle.
  const T angle =2. * atan2(normalized_quaternion.vec().norm(), normalized_quaternion.w());
  constexpr double kCutoffAngle = 1e-7;  // We linearize below this angle.
  const T scale = angle < kCutoffAngle ? T(2.) : angle / sin(angle / 2.);
  return Eigen::Matrix<T, 3, 1>(scale * normalized_quaternion.x(),
                                scale * normalized_quaternion.y(),
                                scale * normalized_quaternion.z());
}

tip_2:传感器坐标系下的一障碍物点(x,y)转换到map坐标系下。
理论:
已知障碍物点在传感器坐标系下坐标为 ( l a s e r x , l a s e r y ) (laser_x,laser_y) (laserx,lasery),传感器坐标系原点在车体坐标系下的坐标为 ( x 2 , y 2 , t h e t a 2 ) (x2,y2,theta_2) (x2,y2,theta2),车体坐标原点在map坐标系下的坐标为 ( x 1 , y 1 , t h e t a 1 ) (x1,y1,theta_1) (x1,y1,theta1)
1)先计算传感器坐标系原点在map坐标系下的位置 ( x , y ) (x,y) x,y)
x = x 1 + x 2 ∗ c o s ( t h e t a 1 ) − y 2 ∗ s i n ( t h e t a 1 ) x=x_1+x_2*cos(theta_1)-y_2*sin(theta_1) x=x1+x2cos(theta1)y2sin(theta1)
y = y 1 + x 2 ∗ s i n ( t h e t a 1 ) + y 2 ∗ s i n ( t h e t a 1 ) y=y_1+x_2*sin(theta_1)+y_2*sin(theta_1) y=y1+x2sin(theta1)+y2sin(theta1)
t h e t a = a c t a n 2 ( ( s i n ( t h e t a 1 + t h e t a 2 ) / c o s ( t h e t a 1 + t h e t a 2 ) ) theta=actan2((sin(theta_1+theta_2)/cos(theta_1+theta_2)) theta=actan2((sin(theta1+theta2)/cos(theta1+theta2))
2)传感器坐标系下的障碍物点在map坐标系下的位置 ( x 0 , y 0 ) (x_0,y_0) (x0,y0)
x 0 = x + l a s e r x ∗ c o s ( t h e t a 1 + t h e t a 2 ) x_0=x+laser_x*cos(theta_1+theta_2) x0=x+laserxcos(theta1+theta2)
y 0 = y + l a s e r y ∗ s i n ( t h e t a 1 + t h e t a 2 ) y_0=y+laser_y*sin(theta_1+theta_2) y0=y+laserysin(theta1+theta2)
代码:

Eigen::Vector2f offset_r2b;//rgbd2baselink
        Eigen::Vector2f offset_b2m;//baselink2map
        double yaw_r2b;
        double yaw_b2m;
        offset_r2b[0]=RGBD_TO_BASELINK.getOrigin().x();
        offset_r2b[1]=RGBD_TO_BASELINK.getOrigin().y();
        yaw_r2b=tf::getYaw(RGBD_TO_BASELINK.getRotation());

        offset_b2m[0]=robot_position[0];
        offset_b2m[1]=robot_position[1];
        yaw_b2m=robot_angle[2];
        for(int i=0;i<ori_obs_list.size();++i)
        {
            Eigen::Vector2f tmp_center;
            tmp_center[0]=(cos(yaw_b2m)*cos(yaw_r2b) - sin(yaw_b2m)*sin(yaw_r2b))*ori_obs_list[i].bounding_box_.pose.position.x
                        -(cos(yaw_b2m)*sin(yaw_r2b) + sin(yaw_b2m)*cos(yaw_r2b))*ori_obs_list[i].bounding_box_.pose.position.y
                        +cos(yaw_b2m)*offset_r2b[0] - sin(yaw_b2m)*offset_r2b[1] + offset_b2m[0];
            tmp_center[1]=(sin(yaw_b2m)*cos(yaw_r2b) + cos(yaw_b2m)*sin(yaw_r2b))*ori_obs_list[i].bounding_box_.pose.position.x
                        -(sin(yaw_b2m)*sin(yaw_r2b) - cos(yaw_b2m)*cos(yaw_r2b))*ori_obs_list[i].bounding_box_.pose.position.y
                        +sin(yaw_b2m)*offset_r2b[0] 
         }

tip_3:车体坐标系下的一个障碍物点,转换到地图坐标系下的两种实现方式:
方式1:
算法开发调试过程中的tips(持续更新)_第1张图片
这里借用作者陈光在《无人驾驶干货铺》中一张坐标变换的图解。
算法开发调试过程中的tips(持续更新)_第2张图片
所以,这里假设车体坐标系下一个障碍物点为(x1,y1),车辆在地图坐标系下的位姿为(x’,y’,α)。那么障碍物点在地图坐标系下的坐标(x,y)为:
x = x ′ + x 1 c o s α − y 1 s i n α x=x'+x1cosα-y1sinα x=x+x1cosαy1sinα
y = y ′ + x 1 s i n α + y 1 c o s α y=y'+x1sinα+y1cosα y=y+x1sinα+y1cosα
方式2:利用tf::transform

tf::Vector3 p_v(x1,y1,0);
p_v=transform(p_v);//transform为车体到map的坐标变换关系
pcl::PointXYZ p_inMap;
p_inMap.x=p_inMap.getX();
p_inMap.y=p_inMap.getY();
p_inMap.z=0;

tip_4:最近在看到一些代码对Eigen::ArrayXXd的乘法产生疑问,对此作出测试:

#include
#include
#include
#include
using namespace std;
int main()
{
    size_t n_pts = 4;
    Eigen::ArrayXXd ranges (n_pts, 2);
    Eigen::ArrayXXd output (n_pts, 2);
    Eigen::ArrayXXd co_sine_ (n_pts, 2);

    for (size_t i = 0; i < n_pts; ++i)
    {
        ranges (i, 0) = i;
        ranges (i, 1) = i;
        co_sine_ (i, 0) = cos (M_PI/2);
        co_sine_ (i, 1) = sin (M_PI/2);
    }
    output = ranges * co_sine_;
    for(size_t i=0;i<n_pts;++i)
    {
        std::cout<<output(i,0)<<","<<output(i,1)<<std::endl;
    }
    return 0;
}

结果仍然是一个4行2列的数组

0,0
6.12323e-17,1
1.22465e-16,2
1.83697e-16,3

你可能感兴趣的:(应用类)