⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wavefront.cc

📁 机器人仿真软件
💻 CC
📖 第 1 页 / 共 3 页
字号:
  return 0;}voidWavefront::ProcessCommand(player_planner_cmd_t* cmd){  double new_x, new_y, new_a;  //double eps = 1e-3;  new_x = cmd->goal.px;  new_y = cmd->goal.py;  new_a = cmd->goal.pa;#if 0  if((fabs(new_x - this->target_x) > eps) ||     (fabs(new_y - this->target_y) > eps) ||     (fabs(this->angle_diff(new_a,this->target_a)) > eps))  {#endif    this->target_x = new_x;    this->target_y = new_y;    this->target_a = new_a;    printf("new goal: %f, %f, %f\n", target_x, target_y, target_a);    this->new_goal = true;    this->atgoal = false;#if 0  }#endif}voidWavefront::ProcessLocalizeData(player_position2d_data_t* data){  this->localize_x = data->pos.px;  this->localize_y = data->pos.py;  this->localize_a = data->pos.pa;}voidWavefront::ProcessPositionData(player_position2d_data_t* data){  this->position_x = data->pos.px;  this->position_y = data->pos.py;  this->position_a = data->pos.pa;}voidWavefront::ProcessMapInfo(player_map_info_t* info){  // Got new map info pushed to us.  We'll save this info and get the new  // map.  this->plan->scale = info->scale;  this->plan->size_x = info->width;  this->plan->size_y = info->height;  this->plan->origin_x = info->origin.px;  this->plan->origin_y = info->origin.py;  // Set the bounds to search the whole grid.  plan_set_bounds(this->plan,                  0, 0, this->plan->size_x - 1, this->plan->size_y - 1);  // Now get the map data, possibly in separate tiles.  if(this->GetMap(true) < 0)  {    this->have_map = false;    this->StopPosition();  }  else  {    this->have_map = true;    this->new_map = true;    // force replanning    if(this->curr_waypoint >= 0)      this->new_goal = true;  }}voidWavefront::PutPlannerData(){  player_planner_data_t data;  memset(&data,0,sizeof(data));  if(this->waypoint_count > 0)    data.valid = 1;  else    data.valid = 0;  if((this->waypoint_count > 0) && (this->curr_waypoint < 0))    data.done = 1;  else    data.done = 0;  // put the current localize pose  data.pos.px = this->localize_x;  data.pos.py = this->localize_y;  data.pos.pa = this->localize_a;  data.goal.px = this->target_x;  data.goal.py = this->target_y;  data.goal.pa = this->target_a;  if(data.valid && !data.done)  {    data.waypoint.px = this->waypoint_x;    data.waypoint.py = this->waypoint_y;    data.waypoint.pa = this->waypoint_a;    data.waypoint_idx = this->curr_waypoint;    data.waypoints_count = this->waypoint_count;  }  this->Publish(this->device_addr, NULL,                PLAYER_MSGTYPE_DATA,                PLAYER_PLANNER_DATA_STATE,                (void*)&data,sizeof(data),NULL);}voidWavefront::PutPositionCommand(double x, double y, double a, unsigned char type){  player_position2d_cmd_vel_t vel_cmd;  player_position2d_cmd_pos_t pos_cmd;  memset(&vel_cmd,0,sizeof(vel_cmd));  memset(&pos_cmd,0,sizeof(pos_cmd));  if(type)  {    // position control    pos_cmd.pos.px = x;    pos_cmd.pos.py = y;    pos_cmd.pos.pa = a;    pos_cmd.state=1;    this->position->PutMsg(this->InQueue,                         PLAYER_MSGTYPE_CMD,                         PLAYER_POSITION2D_CMD_POS,                         (void*)&pos_cmd,sizeof(pos_cmd),NULL);  }  else  {    // velocity control (used to stop the robot)    vel_cmd.vel.px = x;    vel_cmd.vel.py = y;    vel_cmd.vel.pa = a;    vel_cmd.state=1;    this->position->PutMsg(this->InQueue,                         PLAYER_MSGTYPE_CMD,                         PLAYER_POSITION2D_CMD_VEL,                         (void*)&vel_cmd,sizeof(vel_cmd),NULL);  }}voidWavefront::LocalizeToPosition(double* px, double* py, double* pa,                              double lx, double ly, double la){  double offset_x, offset_y, offset_a;  double lx_rot, ly_rot;  offset_a = this->angle_diff(this->position_a,this->localize_a);  lx_rot = this->localize_x * cos(offset_a) - this->localize_y * sin(offset_a);  ly_rot = this->localize_x * sin(offset_a) + this->localize_y * cos(offset_a);  offset_x = this->position_x - lx_rot;  offset_y = this->position_y - ly_rot;  //printf("offset: %f, %f, %f\n", offset_x, offset_y, RTOD(offset_a));  *px = lx * cos(offset_a) - ly * sin(offset_a) + offset_x;  *py = lx * sin(offset_a) + ly * cos(offset_a) + offset_y;  *pa = la + offset_a;}voidWavefront::StopPosition(){  if(!this->stopped)  {    //puts("stopping robot");    PutPositionCommand(0.0,0.0,0.0,0);    this->stopped = true;  }}voidWavefront::SetWaypoint(double wx, double wy, double wa){  double wx_odom, wy_odom, wa_odom;  // transform to odometric frame  LocalizeToPosition(&wx_odom, &wy_odom, &wa_odom, wx, wy, wa);  // hand down waypoint  //printf("sending waypoint: %.3f %.3f %.3f\n",         //wx_odom, wy_odom, RTOD(wa_odom));  PutPositionCommand(wx_odom, wy_odom, wa_odom,1);  // cache this waypoint, odometric coords  this->waypoint_odom_x = wx_odom;  this->waypoint_odom_y = wy_odom;  this->waypoint_odom_a = wa_odom;  this->stopped = false;}////////////////////////////////////////////////////////////////////////////////// Main function for device threadvoid Wavefront::Main(){  double dist, angle;  double t;  double last_replan_lx=0.0, last_replan_ly=0.0;  double last_replan_time = 0.0;  double last_publish_time = 0.0;  double replan_timediff, replan_dist;  bool rotate_waypoint=false;  bool replan;  pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);  // block until we get initial data from underlying devices  // TODO  //this->position->Wait();  this->StopPosition();  for(;;)  {    pthread_testcancel();    ProcessMessages();    if(!this->have_map && !this->new_map_available)    {      usleep(CYCLE_TIME_US);      continue;    }    GlobalTime->GetTimeDouble(&t);    if((t - last_publish_time) > 0.25)    {      last_publish_time = t;      this->PutPlannerData();    }    // Is it time to replan?    replan_timediff = t - last_replan_time;    replan_dist = sqrt(((this->localize_x - last_replan_lx) *                        (this->localize_x - last_replan_lx)) +                       ((this->localize_y - last_replan_ly) *                        (this->localize_y - last_replan_ly)));    replan = (this->replan_dist_thresh >= 0.0) &&            (replan_dist > this->replan_dist_thresh) &&            (this->replan_min_time >= 0.0) &&            (replan_timediff > this->replan_min_time) &&            !this->atgoal;    // Did we get a new goal, or is it time to replan?    if(this->new_goal || replan)    {#if 0      // Should we get a new map?      if(this->new_map_available)      {        this->new_map_available = false;        if(this->GetMapInfo(true) < 0)          PLAYER_WARN("failed to get new map info");        else        {          if(this->GetMap(true) < 0)            PLAYER_WARN("failed to get new map data");          else          {            this->new_map = true;            this->have_map = true;          }        }      }      // We need to recompute the C-space if the map changed, or if the      // goal or robot pose lie outside the bounds of the area we last      // searched.      if(this->new_map ||         !plan_check_inbounds(plan,this->localize_x,this->localize_y) ||          !plan_check_inbounds(plan,this->target_x,this->target_y))      {        // Unfortunately, this computation can take a while (e.g., 1-2        // seconds).  So we'll stop the robot while it thinks.        this->StopPosition();        // Set the bounds to search only an axis-aligned bounding box        // around the robot and the goal.        plan_set_bbox(this->plan, 1.0, 3.0,                      this->localize_x, this->localize_y,                      this->target_x, this->target_y);        struct timeval t0, t1;        gettimeofday(&t0, NULL);        plan_update_cspace(this->plan,this->cspace_fname);        gettimeofday(&t1, NULL);        printf("time to update: %f\n",               (t1.tv_sec + t1.tv_usec/1e6) -               (t0.tv_sec + t0.tv_usec/1e6));        this->new_map = false;      }#endif      // compute costs to the new goal      plan_update_plan(this->plan, this->target_x, this->target_y);      // compute a path to the goal from the current position      plan_update_waypoints(this->plan, this->localize_x, this->localize_y);#if 0      if(this->plan->waypoint_count == 0)      {        // No path.  If we only searched a bounding box last time, grow the        // bounds to encompass the whole map and try again.        if((plan->min_x > 0) || (plan->max_x < (plan->size_x - 1)) ||           (plan->min_y > 0) || (plan->max_y < (plan->size_y - 1)))        {          // Unfortunately, this computation can take a while (e.g., 1-2          // seconds).  So we'll stop the robot while it thinks.          this->StopPosition();          // Set the bounds to search the whole grid.          plan_set_bounds(this->plan, 0, 0,                          this->plan->size_x - 1,                          this->plan->size_y - 1);          struct timeval t0, t1;          gettimeofday(&t0, NULL);          plan_update_cspace(this->plan,this->cspace_fname);          gettimeofday(&t1, NULL);          printf("time to update: %f\n",               (t1.tv_sec + t1.tv_usec/1e6) -               (t0.tv_sec + t0.tv_usec/1e6));          // compute costs to the new goal          plan_update_plan(this->plan, this->target_x, this->target_y);          // compute a path to the goal from the current position          plan_update_waypoints(this->plan,                                this->localize_x,                                this->localize_y);        }      }#endif      if(this->plan->waypoint_count == 0)      {        fprintf(stderr, "Wavefront (port %d):\n  "                "No path from (%.3lf,%.3lf,%.3lf) to (%.3lf,%.3lf,%.3lf)\n",                this->device_addr.robot,                this->localize_x,                this->localize_y,                RTOD(this->localize_a),                this->target_x,                this->target_y,                RTOD(this->target_a));        // Only fail here if this is our first try at making a plan;        // if we're replanning and don't find a path then we'll just stick        // with the old plan.        if(this->curr_waypoint < 0)        {          //this->curr_waypoint = -1;          this->new_goal=false;          this->waypoint_count = 0;        }      }      else if(this->plan->waypoint_count > PLAYER_PLANNER_MAX_WAYPOINTS)      {        PLAYER_WARN("Plan exceeds maximum number of waypoints!");        this->waypoint_count = PLAYER_PLANNER_MAX_WAYPOINTS;      }      else        this->waypoint_count = this->plan->waypoint_count;      if(this->plan->waypoint_count > 0)      {        for(int i=0;i<this->plan->waypoint_count;i++)        {          double wx, wy;          plan_convert_waypoint(this->plan,                                this->plan->waypoints[i],                                &wx, &wy);          this->waypoints[i][0] = wx;          this->waypoints[i][1] = wy;        }        this->curr_waypoint = 0;        this->new_goal = true;      }      last_replan_time = t;      last_replan_lx = this->localize_x;      last_replan_ly = this->localize_y;    }    if(!this->enable)    {      this->StopPosition();      usleep(CYCLE_TIME_US);      continue;    }    bool going_for_target = (this->curr_waypoint == this->plan->waypoint_count);    dist = sqrt(((this->localize_x - this->target_x) *                 (this->localize_x - this->target_x)) +                ((this->localize_y - this->target_y) *                 (this->localize_y - this->target_y)));    // Note that we compare the current heading and waypoint heading in the    // *odometric* frame.   We do this because comparing the current    // heading and waypoint heading in the localization frame is unreliable    // when making small adjustments to achieve a desired heading (i.e., the    // robot gets there and VFH stops, but here we don't realize we're done    // because the localization heading hasn't changed sufficiently).    angle = fabs(this->angle_diff(this->waypoint_odom_a,this->position_a));    if(going_for_target && dist < this->dist_eps && angle < this->ang_eps)    {      // we're at the final target, so stop      StopPosition();      this->curr_waypoint = -1;      this->new_goal = false;      this->atgoal = true;    }    else if(this->curr_waypoint < 0)    {      // no more waypoints, so stop      StopPosition();    }    else    {      // are we there yet?  ignore angle, cause this is just a waypoint      dist = sqrt(((this->localize_x - this->waypoint_x) *                   (this->localize_x - this->waypoint_x)) +                  ((this->localize_y - this->waypoint_y) *                   (this->localize_y - this->waypoint_y)));      // Note that we compare the current heading and waypoint heading in the      // *odometric* frame.   We do this because comparing the current      // heading and waypoint heading in the localization frame is unreliable

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -