打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
costmap2world
#include <stdio.h>
#include <math.h>

#define PI 3.141592

#define ROBOT_ORIGIN_X 

/* in 
 * para 1: costmap原点在world坐标系的 x
 * para 2: costmap原点在world坐标系的 y 

 * para 3: 机器人在world坐标系的 x
 * para 4: 机器人在world坐标系的 y
 * para 5: 机器人在world坐标系旋转的弧度值
 
 * para 6: p点在world坐标系的 x
 * para 7: p点在world坐标系的 y

 * out
 * para 8: p点在map坐标系的 x
 * para 9: p点在map坐标系的 y

 1、world_frame 世界坐标系,第一个主坐标系
 2、costmap_frame 局部地图坐标系
 3、设以robot位置为原点与world坐标系姿态相同的坐标系为r_frame
 4、设以robot位置为原点相对world坐标系旋转w的坐标系为rw_frame

*/

#if 1
int world2map(double w_costmap_origin_x,double w_costmap_origin_y,
    double w,
    double w_p_x,double w_p_y,
    double &m_x,double &m_y)
{
if(w_costmap_origin_x == w_p_x && w_costmap_origin_y == w_p_y)
{
m_x = 0;
m_y = 0;
return 0;
}

// 1、计算点p(w_P_x,w_p_y)在map1_frame上的坐标值。
double r_p_x = w_p_x - w_costmap_origin_x;
double r_p_y = w_p_y - w_costmap_origin_y;

// 2、计算P点与机器人相连的线段长
double l_p_r = hypot(r_p_x, r_p_y);

// 3、计算l_p_r与map1_frame x轴正方向上的夹角
double r_frame_a = 0;
if(0 == r_p_x && r_p_y > 0)
{
r_frame_a = PI/2.0;
}
else if(0 == r_p_x && r_p_y < 0)
{
r_frame_a = 3*PI/2.0;
}
else
{
r_frame_a = atan2(r_p_y, r_p_x);
}

// 4、计算l_p_r与map_frame x轴正方向上的夹角
double rw_frame_a = r_frame_a - w;

// 5、计算点p(w_P_x,w_p_y)在mapw_frame上的坐标值。
m_x = l_p_r*cos(rw_frame_a);
m_y = l_p_r*sin(rw_frame_a);

return 0;
}

int map2world(double w_costmap_origin_x,double w_costmap_origin_y,
    double w,
    double m_p_x,double m_p_y,
    double &w_x,double &w_y)
{
// 1、计算点p(w_P_x,w_p_y)在rw_frame上的坐标值。
double rw_p_x = m_p_x - w_costmap_origin_x;
double rw_p_y = m_p_y - w_costmap_origin_y;

// 2、计算P点与机器人相连的线段长
double l_p_r = hypot(m_p_x, m_p_y);

// 3、计算l_p_r与map_frame x轴正方向上的夹角
double map_frame_a = 0;
if(0 == m_p_x && m_p_y > 0)
{
map_frame_a = PI/2.0;
}
else if(0 == m_p_x && m_p_y < 0)
{
map_frame_a = 3*PI/2.0;
}
else
{
map_frame_a = atan2(m_p_x, m_p_x);
}

// 4、计算l_p_r与r_frame x轴正方向上的夹角
double map1_frame_a = map_frame_a + w;

// 5、计算点p(m_P_x,m_p_y)在r_frame上的坐标值。
double map1_p_x = l_p_r*cos(map1_frame_a);
double map1_p_y = l_p_r*sin(map1_frame_a);

// 6、计算点p(w_P_x,w_p_y)在world_frame上的坐标值。
w_x = map1_p_x - w_costmap_origin_x;
w_y = map1_p_x - w_costmap_origin_y;
return 0;
}



#else
int world2map(double w_costmap_origin_x,double w_costmap_origin_y,
    double w_robot_x,double w_robot_y,double w,
    double w_p_x,double w_p_y,
    double &m_x,double &m_y)
{
if(w_robot_x == w_p_x && w_robot_y == w_p_y)
{
m_x = w_p_x;
m_y = w_p_y;
return 0;
}

// 1、计算点p(w_P_x,w_p_y)在r_frame上的坐标值。
double r_p_x = w_p_x - w_robot_x;
double r_p_y = w_p_y - w_robot_y;

// 2、计算P点与机器人相连的线段长
double l_p_r = hypot(r_p_x, r_p_y);

// 3、计算l_p_r与r_frame x轴正方向上的夹角
double r_frame_a = 0;
if(0 == r_p_x && r_p_y > 0)
{
r_frame_a = PI/2.0;
}
else if(0 == r_p_x && r_p_y < 0)
{
r_frame_a = 3*PI/2.0;
}
else
{
r_frame_a = atan2(r_p_y, r_p_x);
}

// 4、计算l_p_r与rw_frame x轴正方向上的夹角
double rw_frame_a = r_frame_a - w;

// 5、计算点p(w_P_x,w_p_y)在rw_frame上的坐标值。
double rw_p_x = l_p_r*cos(rw_frame_a);
double rw_p_y = l_p_r*sin(rw_frame_a);

// 6、计算点p(w_P_x,w_p_y)在costmap_frame上的坐标值。
m_x = rw_p_x - w_costmap_origin_x;
m_y = rw_p_y - w_costmap_origin_y;

return 0;
}

int map2world(double w_costmap_origin_x,double w_costmap_origin_y,
    double w_robot_x,double w_robot_y,double w,
    double m_p_x,double m_p_y,
    double &w_x,double &w_y)
{
// 1、计算点p(w_P_x,w_p_y)在rw_frame上的坐标值。
double rw_p_x = m_p_x - w_costmap_origin_x;
double rw_p_y = m_p_y - w_costmap_origin_y;

// 2、计算P点与机器人相连的线段长
double l_p_r = hypot(rw_p_x, rw_p_y);

// 3、计算l_p_r与rw_frame x轴正方向上的夹角
double rw_frame_a = 0;
if(0 == rw_p_x && rw_p_y > 0)
{
rw_frame_a = PI/2.0;
}
else if(0 == rw_p_x && rw_p_y < 0)
{
rw_frame_a = 3*PI/2.0;
}
else
{
rw_frame_a = atan2(rw_p_x, rw_p_y);
}

// 4、计算l_p_r与r_frame x轴正方向上的夹角
double r_frame_a = rw_frame_a + w;

// 5、计算点p(m_P_x,m_p_y)在r_frame上的坐标值。
double r_p_x = l_p_r*cos(r_frame_a);
double r_p_y = l_p_r*sin(r_frame_a);

// 6、计算点p(w_P_x,w_p_y)在world_frame上的坐标值。
w_x = r_p_x - w_costmap_origin_x;
w_y = r_p_y - w_costmap_origin_y;
return 0;
}
#endif

/* in
 * para 1: 机器人在world坐标系的 x
 * para 2: 机器人在world坐标系的 y
 * para 3: 机器人在world坐标系旋转的弧度值

 * para 4: map width在x轴长度
 * para 5: map height在y轴长度

 * out
 * para 6: map在world坐标系的 x
 * para 7: map在world坐标系的 y
**/
int get_map_origin(double w_robot_x,double w_robot_y,double w,
double width, double height,
double &map_origin_x,double &map_origin_y)
{
if(0 == width || 0 == height)
{
printf("T error width[%f] height[%f]\n", width, height);
return -1;
}

#if 0
// 1、计算P点与机器人相连的线段长
double l_p_r = hypot(width, height);

// 2、计算l_p_r与r_frame x轴正方向上的夹角
double r_frame_a = atan2(width, height) + PI;

// 3、计算点map_origin在r_frame上的坐标值
double r_map_origin_x = l_p_r*cos(r_frame_a+w);
double r_map_origin_y = l_p_r*sin(r_frame_a+w);

// 4、计算点map_origin在world_frame上的坐标值
map_origin_x = r_map_origin_x + w_robot_x;
map_origin_y = r_map_origin_y + w_robot_y;
#else
map_origin_x = hypot(width, height)*cos(atan2(width, height) + w + PI) + w_robot_x;
map_origin_y = hypot(width, height)*sin(atan2(width, height) + w + PI) + w_robot_y;
#endif
return 0;
}

int main()
{
double map_origin_x, map_origin_y;
double w_robot_x = 0, w_robot_y = 0, w = 0;
double width = 4, height = 4;

// 测试初始值
for(double i=0; i<4; i++)
{
w = i*PI/2.0;
get_map_origin(w_robot_x,w_robot_y,w,width,height,map_origin_x,map_origin_y);
printf("T ---- map_origin_x[%f]  map_origin_y[%f]\n", map_origin_x, map_origin_y);
}

double w_p_x = 0;
double w_p_y = 0;

double m_x = 0;
double m_y = 0;

double m_p_x = 0;
double m_p_y = 0;

double w_x;
double w_y;

int world2map(map_origin_x,map_origin_y,w,w_p_x,w_p_y,m_x,m_y);
int map2world(map_origin_x,map_origin_y,w,m_p_x,m_p_y,w_x,w_y);
return 0;
}

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
使用R语言展示我们生信技能树全国巡讲的征程
彻底理解position与anchorPoint
开源机器人库orocos KDL 学习笔记二:Geometric
arcgis api for silverlight开发系列之三:定义坐标系
旋转Frame后的坐标
让ros机器人行走、建图、路径规划、定位和导航
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服