📄 khepera.cc
字号:
* 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 + -