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

📄 khepera.cc

📁 机器人仿真软件
💻 CC
📖 第 1 页 / 共 2 页
字号:
 * returns: 0 on success */int Khepera::Setup(){  // open and initialize the serial to -> Khepera    printf("Khepera: connection initializing (%s)...", this->khepera_serial_port);  fflush(stdout);  Serial = new KheperaSerial(geometry->PortName,KHEPERA_BAUDRATE);  if (Serial == NULL || !Serial->Open())  {    return 1;  }  printf("Done\n");  refresh_last_position = false;  motors_enabled = false;  velocity_mode = true;  direct_velocity_control = false;  desired_heading = 0;  /* now spawn reading thread */  StartThread();  return(0);}int Khepera::Shutdown(){  printf("Khepera: SHUTDOWN\n");  StopThread();  // Killing the thread seems to leave out serial  // device in a bad state, need to fix this,  // till them we just dont stop the robot  // which is theoretically quite bad...but this is the khepera...  // it cant do that much damage its only 7cm across  //SetSpeed(0,0);  delete Serial;  Serial = NULL;  return(0);}void Khepera::Main(){  int last_position_subscrcount=0;  pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);  while (1)   {    // we want to reset the odometry and enable the motors if the first     // client just subscribed to the position device, and we want to stop     // and disable the motors if the last client unsubscribed.    if(!last_position_subscrcount && this->position_subscriptions)    {      printf("Khepera: first pos sub. turn off and reset\n");      // then first sub for pos, so turn off motors and reset odom      SetSpeed(0,0);      ResetOdometry();    }     else if(last_position_subscrcount && !(this->position_subscriptions))    {      // last sub just unsubbed      printf("Khepera: last pos sub gone\n");      SetSpeed(0,0);    }    last_position_subscrcount = this->position_subscriptions;	ProcessMessages();    pthread_testcancel();    // now lets get new data...    UpdateData();    pthread_testcancel();  }  pthread_exit(NULL);}/* this will update the data that is sent to clients * just call separate functions to take care of it * * returns: */voidKhepera::UpdateData(){  player_position2d_data_t position_data;  player_ir_data_t ir_data;  UpdatePosData(&position_data);  // put position data  Publish(position_addr,NULL,PLAYER_MSGTYPE_DATA, PLAYER_POSITION2D_DATA_STATE, (unsigned char *) &position_data, sizeof(player_position2d_data_t),NULL);  UpdateIRData(&ir_data);  // put ir data  Publish(position_addr,NULL,PLAYER_MSGTYPE_DATA, PLAYER_IR_DATA_RANGES, (unsigned char *) &ir_data, sizeof(ir_data),NULL);}/* this will update the IR part of the client data * it entails reading the currently active IR sensors * and then changing their state to off and turning on * 2 new IRs.   * * returns: */voidKhepera::UpdateIRData(player_ir_data_t * d){  ReadAllIR(d);  d->ranges_count = geometry->ir.poses_count;  for (unsigned int i =0; i < geometry->ir.poses_count; i++)   {    d->ranges[i] = geometry->scale * geometry->ir_calib_a[i] * pow(d->voltages[i],geometry->ir_calib_b[i]);    d->voltages[i] = d->voltages[i];  }}  /* this will update the position data.  this entails odometry, etc */ voidKhepera::UpdatePosData(player_position2d_data_t *d){  // calculate position data  int pos_left, pos_right;  Khepera::ReadPos(&pos_left, &pos_right);  int change_left = pos_left - last_lpos;  int change_right = pos_right - last_rpos;  last_lpos = pos_left;  last_rpos = pos_right;  double transchange = (change_left + change_right) * geometry->encoder_res / 2;  double rotchange = (change_left - change_right) * geometry->encoder_res / 2;  double dx,dy,Theta;  double r = geometry->position.size.sw*geometry->scale/2;  if (transchange == 0)  {    Theta = 360 * rotchange/(2 * M_PI * r);	    dx = dy= 0;  }  else if (rotchange == 0)  {    dx = transchange;    dy = 0;    Theta = 0;  }  else  {    Theta = 360 * rotchange/(2 * M_PI * r);    double R = transchange * r / rotchange;    dy = R - R*cos(Theta*M_PI/180);    dx = R*sin(Theta*M_PI/180);  }  // add code to read in the speed data  int left_vel, right_vel;  Khepera::ReadSpeed(&left_vel, &right_vel);  double lv = left_vel * geometry->encoder_res;  double rv = right_vel * geometry->encoder_res;  double trans_vel = 100 * (lv + rv)/2;  double rot_vel = (lv - rv)/2;  double rot_vel_deg = 100 * 360 * rot_vel/(2 * M_PI * r);  // now write data  double rad_Theta = DTOR(yaw);  x+=(dx*cos(rad_Theta) + dy*sin(rad_Theta));  y+=(dy*cos(rad_Theta) + dx*sin(rad_Theta));  d->pos.px = x/geometry->scale;  d->pos.py = y/geometry->scale;  yaw += Theta;  while (yaw > 360) yaw -= 360;  while (yaw < 0) yaw += 360;  d->pos.pa = DTOR(yaw);  d->vel.px = trans_vel/geometry->scale;  d->vel.pa = DTOR(rot_vel_deg);}/* this will set the odometry to a given position * ****NOTE: assumes that the arguments are in network byte order!***** * * returns:  */intKhepera::ResetOdometry(){  printf("Reset Odometry\n");  int Values[2];  Values[0] = 0;  Values[1] = 0;  if (Serial->KheperaCommand('G',2,Values,0,NULL) < 0)    return -1;  last_lpos = 0;  last_rpos = 0;  player_position2d_data_t data;  memset(&data,0,sizeof(player_position2d_data_t));  Publish(position_addr, NULL, PLAYER_MSGTYPE_DATA, PLAYER_POSITION2D_DATA_STATE, &data, sizeof(data),NULL);  x=y=yaw=0;  return 0;}/* this will read the given AD channel * * returns: the value of the AD channel *//*unsigned shortREB::ReadAD(int channel) {  char buf[64];  sprintf(buf, "I,%d\r", channel);  write_command(buf, strlen(buf), sizeof(buf));    return atoi(&buf[2]);}*//* reads all the IR values at once.  stores them * in the uint16_t array given as arg ir * * returns:  */intKhepera::ReadAllIR(player_ir_data_t* d){  int Values[PLAYER_IR_MAX_SAMPLES];  // changed these variable-size array declarations to the   // bigger-than-necessary ones above, because older versions of gcc don't  // support variable-size arrays.  if(Serial->KheperaCommand('N',0,NULL,geometry->ir.poses_count,Values) < 0)    return -1;			  for (unsigned int i=0; i< geometry->ir.poses_count; ++i)  {    d->voltages[i] = static_cast<short> (Values[i]);  }  return 0;}/* this will set the desired speed for the given motor mn * * returns: */intKhepera::SetSpeed(int speed1, int speed2){	int Values[2];	Values[0] = speed1;	Values[1] = speed2;	return Serial->KheperaCommand('D',2,Values,0,NULL);}/* reads the current speed of motor mn * * returns: the speed of mn */intKhepera::ReadSpeed(int * left,int * right){	int Values[2];	if (Serial->KheperaCommand('E',0,NULL,2,Values) < 0)		return -1;	*left = Values[0];	*right = Values[1];	return 0;}/* this sets the desired position motor mn should go to * * returns: *//*voidREB::SetPos(int mn, int pos){  char buf[64];    sprintf(buf,"C,%c,%d\r", '0'+mn,pos);  write_command(buf, strlen(buf), sizeof(buf));}*//* this sets the position counter of motor mn to the given value * * returns: */intKhepera::SetPosCounter(int pos1, int pos2){	int Values[2];	Values[0] = pos1;	Values[1] = pos2;	return Serial->KheperaCommand('G',2,Values,0,NULL);}/* this will read the current value of the position counter * for motor mn * * returns: the current position for mn */intKhepera::ReadPos(int * pos1, int * pos2){	int Values[2];	if (Serial->KheperaCommand('H',0,NULL,2,Values) < 0)		return -1;	*pos1 = Values[0];	*pos2 = Values[1];	return 0;}/* this will configure the position PID for motor mn * using paramters Kp, Ki, and Kd * * returns: *//*voidREB::ConfigPosPID(int mn, int kp, int ki, int kd){   char buf[64];  sprintf(buf, "F,%c,%d,%d,%d\r", '0'+mn, kp,ki,kd);  write_command(buf, strlen(buf), sizeof(buf));}*//* this will configure the speed PID for motor mn * * returns: *//*voidREB::ConfigSpeedPID(int mn, int kp, int ki, int kd){  char buf[64];    sprintf(buf, "A,%c,%d,%d,%d\r", '0'+mn, kp,ki,kd);    write_command(buf, strlen(buf), sizeof(buf));}*//* this will set the speed profile for motor mn * it takes the max velocity and acceleration * * returns: *//*voidREB::ConfigSpeedProfile(int mn, int speed, int acc){  char buf[64];    sprintf(buf, "J,%c,%d,%d\r", '0'+mn, speed,acc);  write_command(buf, strlen(buf), sizeof(buf));}*//* this will read the status of the motion controller. * mode is set to 1 if in position mode, 0 if velocity mode * error is set to the position/speed error * * returns: target status: 1 is on target, 0 is not on target *//*unsigned charKhepera::ReadStatus(int mn, int *mode, int *error){  char buf[64];  sprintf(buf, "K,%c\r", '0'+mn);  //write_command(buf, strlen(buf), sizeof(buf));  // buf now has the form "k,target,mode,error"  int target;  sscanf(buf, "k,%d,%d,%d", &target, mode, error);  return (unsigned char)target;}*/

⌨️ 快捷键说明

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