Khepera III 工具箱/工具箱/模組/khepera3
khepera3 模組提供對機器人所有感測器和執行器的訪問,它被分為以下幾個部分
- 通用:韌體版本和時間戳
- 電機:左電機和右電機(分別訪問)
- 驅動:驅動系統(兩個電機)
- 紅外線:紅外感測器,在環境或接近模式下
- 超聲波:超聲波感測器
- 電池:電池電壓、電流和電量
即使每個部分都在單獨的檔案中實現,但包含khepera3.h就足夠了,它包含所有其他檔案。
// Initialize the module
khepera3_init();
// Move the left motor to a specific encoder position
khepera3_motor_stop(&khepera3.motor_left);
khepera3_motor_set_current_position(&khepera3.motor_left, 0);
khepera3_motor_start(&khepera3.motor_left);
khepera3_motor_goto_position(&khepera3.motor_left, 10000);
while (1) {
khepera3_motor_get_current_speed(&khepera3.motor_left);
... = khepera3.motor_left.current_speed;
}
// Set the speed of the robot by setting the speed of both wheels
khepera3_drive_start();
khepera3_drive_set_speed(5000, 5000);
// Set the speed in a differential manner (speed, forward coefficient, turn coefficient, turn coefficient maximum)
khepera3_drive_set_speed_differential(5000., 1., 0.2, 1.);
// Read infrared sensor values
khepera3_infrared_proximity();
int value = khepera3.infrared_proximity.sensor[cKhepera3SensorsInfrared_FrontLeft];
for (i = cKhepera3SensorsInfrared_Begin; i < cKhepera3SensorsInfrared_End; i++) {
weighted_sum += khepera3.infrared_proximity.sensor[i] * weight[i];
}
// Enable and read ultrasound values
khepera3_ultrasound_enable(cKhepera3SensorsUltrasoundBit_Front);
khepera3_ultrasound(cKhepera3SensorsUltrasound_Front);
for (i = 0; i < khepera3.ultrasound.sensor[cKhepera3SensorsUltrasound_Front].echos_count; i++) {
... = khepera3.ultrasound.sensor[cKhepera3SensorsUltrasound_Front].distance[i];
... = khepera3.ultrasound.sensor[cKhepera3SensorsUltrasound_Front].amplitude[i];
}
// Read battery voltage
khepera3_battery_voltage();
float voltage_V = (float)khepera3.battery.voltage * 0.0001;
khepera3 模組構建在稱為khepera3的靜態分配資料結構之上。該結構採用層次結構組織,包含所有感測器和執行器的欄位。一些欄位在模組初始化時設定(khepera3_init),但大多數字段由本模組提供的感測器函式更新。
要獲取任何感測器的測量值,首先呼叫相應的感測器函式(例如 khepera3_infrared_proximity)。當此函式返回時,khepera3 資料結構中的對應欄位將包含新值。一些感測器還返回一個時間戳,它是一個在定期時間間隔內遞增的 32 位計數器。該間隔沒有明確定義,並且計數器溢位(即在達到 2^32-1 後重新開始)。然而,時間戳有時用於找出測量值的定期性。
另一方面,對於執行器函式(例如 khepera3_drive_set_speed),這些值直接作為引數傳遞給函式呼叫,而不是透過khepera3 結構傳遞。請注意,對於所有驅動函式,左電機值在右電機之前指定。
所有函式返回 -1 表示成功,或 0 表示失敗。失敗通常意味著資料無法透過 I2C 匯流排傳輸到負責相應感測器或執行器的微控制器。此類錯誤可能會偶爾出現,並且通常需要冷重啟(關閉,等待幾秒鐘,然後重新開啟)機器人。
因此,不值得實現複雜的錯誤處理程式 - 要麼在這種情況下讓程式崩潰(或無法正常工作),要麼在發生錯誤時乾淨地退出。
由於khepera3 結構是靜態分配的,因此從兩個不同的執行緒呼叫更新相同欄位的函式是不安全的。即呼叫 khepera3_infrared_proximity() 會導致競爭條件。同樣適用於底層的i2cal 模組,它也使用靜態分配的結構。執行緒安全在這裡與程式設計簡單性相沖突,如果這些結構不是靜態分配的,則程式設計簡單性會受到影響。
由於函式和變數名不言自明,因此我們沒有在這裡提供大量的文件,而是列出了每個模組部分的函式、常量和結構。有關更詳盡的文件,請參閱.h 檔案。
khepera3.
dspic.
int i2c_address (const)
int firmware_version
int firmware_revision
motor_left. and motor_right.
int i2c_address (const)
int direction (const)
unsigned int firmware_version
int current_speed
int current_position
int current_torque
enum eKhepera3MotorStatusFlags status
enum eKhepera3MotorErrorFlags error
infrared_ambient. and infrared_proximity.
int sensor[11]
int timestamp
ultrasound.
sensor[5].
int echos_count
int distance[10]
int amplitude[10]
int timestamp[10]
float distance_per_increment (const)
battery.
unsigned int voltage
int current
int current_average
unsigned int capacity_remaining_absolute
unsigned int capacity_remaining_relative
unsigned int temperature
電機函式採用以下之一&(khepera3.motor_left)和&(khepera3.motor_right)作為第一個引數。
// Motor status flags
enum eKhepera3MotorStatusFlags {
cKhepera3MotorStatusFlags_Moving = (1 << 0), // Movement detected
cKhepera3MotorStatusFlags_Direction = (1 << 1), // Direction (0 = negative, 1 = positive)
cKhepera3MotorStatusFlags_OnSetpoint = (1 << 2), // On setpoint
cKhepera3MotorStatusFlags_NearSetpoint = (1 << 3), // Near setpoint
cKhepera3MotorStatusFlags_CommandSaturated = (1 << 4), // Command saturated
cKhepera3MotorStatusFlags_AntiResetWindup = (1 << 5), // Antireset windup active
cKhepera3MotorStatusFlags_SoftwareCurrentControl = (1 << 6), // Software current control active
cKhepera3MotorStatusFlags_SoftStop = (1 << 7), // Softstop active
};
// Motor error flags
enum eKhepera3MotorErrorFlags {
cKhepera3MotorErrorFlags_SampleTimeTooSmall = (1 << 0), // Sample time too small
cKhepera3MotorErrorFlags_WatchdogOverflow = (1 << 1), // Watchdog timer overflow
cKhepera3MotorErrorFlags_BrownOut = (1 << 2), // Brown-out
cKhepera3MotorErrorFlags_SoftwareStop = (1 << 3), // Software stopped motor (if softstop enabled)
cKhepera3MotorErrorFlags_MotorBlocked = (1 << 4), // Motor blocked (if motor blocking enabled)
cKhepera3MotorErrorFlags_PositionOutOfRange = (1 << 5), // Position out of range
cKhepera3MotorErrorFlags_SpeedOutOfRange = (1 << 6), // Speed out of range
cKhepera3MotorErrorFlags_TorqueOutOfRange = (1 << 7), // Torque out of range
};
// Simple functions
int khepera3_motor_initialize(struct sKhepera3Motor *motor);
int khepera3_motor_stop(struct sKhepera3Motor *motor);
int khepera3_motor_start(struct sKhepera3Motor *motor);
int khepera3_motor_idle(struct sKhepera3Motor *motor);
int khepera3_motor_set_speed(struct sKhepera3Motor *motor, int speed);
int khepera3_motor_set_speed_using_profile(struct sKhepera3Motor *motor, int speed);
int khepera3_motor_goto_position(struct sKhepera3Motor *motor, int position);
int khepera3_motor_goto_position_using_profile(struct sKhepera3Motor *motor, int position);
int khepera3_motor_set_current_position(struct sKhepera3Motor *motor, int position);
int khepera3_motor_firmware_version(struct sKhepera3Motor *motor);
int khepera3_motor_get_status(struct sKhepera3Motor *motor);
int khepera3_motor_get_error(struct sKhepera3Motor *motor);
int khepera3_motor_get_current_speed(struct sKhepera3Motor *motor);
int khepera3_motor_get_current_position(struct sKhepera3Motor *motor);
int khepera3_motor_get_current_torque(struct sKhepera3Motor *motor);
// Low-level functions (a list of registers and control types can be found in khepera3_motor.h)
int khepera3_motor_read_register8_p(struct sKhepera3Motor *motor, enum eKhepera3MotorRegister8 reg, unsigned int *result);
int khepera3_motor_read_register16_p(struct sKhepera3Motor *motor, enum eKhepera3MotorRegister16 reg, unsigned int *result);
int khepera3_motor_read_register32_p(struct sKhepera3Motor *motor, enum eKhepera3MotorRegister32 reg, unsigned int *result);
int khepera3_motor_write_register8(struct sKhepera3Motor *motor, enum eKhepera3MotorRegister8 reg, unsigned int value);
int khepera3_motor_write_register16(struct sKhepera3Motor *motor, enum eKhepera3MotorRegister16 reg, unsigned int value);
int khepera3_motor_write_register32(struct sKhepera3Motor *motor, enum eKhepera3MotorRegister32 reg, unsigned int value);
int khepera3_motor_set_control_type(struct sKhepera3Motor *motor, enum eKhepera3MotorControlType control_type);
驅動函式作用於兩個電機,因此使用和修改khepera3 資料結構中的khepera3.motor_left 和khepera3.motor_right。
// Drive functions
void khepera3_drive_stop();
void khepera3_drive_start();
void khepera3_drive_idle();
void khepera3_drive_set_speed(int speed_left, int speed_right);
void khepera3_drive_set_speed_differential(float speed, float forward_coefficient, float differential_coefficient);
void khepera3_drive_set_speed_differential_bounded(float speed, float forward_coefficient, float forward_coefficient_max, float differential_coefficient, float differential_coefficient_max);
void khepera3_drive_set_speed_using_profile(int speed_left, int speed_right);
void khepera3_drive_goto_position(int position_left, int position_right);
void khepera3_drive_goto_position_using_profile(int position_left, int position_right);
void khepera3_drive_set_current_position(int position_left, int position_right);
void khepera3_drive_get_current_speed();
void khepera3_drive_get_current_position();
void khepera3_drive_get_current_torque();
//! Infrared sensors
enum eKhepera3SensorsInfrared {
cKhepera3SensorsInfrared_BackLeft = 0,
cKhepera3SensorsInfrared_Left = 1,
cKhepera3SensorsInfrared_FrontSideLeft = 2,
cKhepera3SensorsInfrared_FrontLeft = 3,
cKhepera3SensorsInfrared_FrontRight = 4,
cKhepera3SensorsInfrared_FrontSideRight = 5,
cKhepera3SensorsInfrared_Right = 6,
cKhepera3SensorsInfrared_BackRight = 7,
cKhepera3SensorsInfrared_Back = 8,
cKhepera3SensorsInfrared_FloorRight = 9,
cKhepera3SensorsInfrared_FloorLeft = 10,
cKhepera3SensorsInfrared_Begin = 0,
cKhepera3SensorsInfrared_End = 10,
cKhepera3SensorsInfrared_Count = 11,
cKhepera3SensorsInfrared_RingBegin = 0,
cKhepera3SensorsInfrared_RingEnd = 9,
cKhepera3SensorsInfrared_RingCount = 9,
cKhepera3SensorsInfrared_FloorBegin = 9,
cKhepera3SensorsInfrared_FloorEnd = 10,
cKhepera3SensorsInfrared_FloorCount = 2
};
// Functions
int khepera3_infrared_ambient();
int khepera3_infrared_ambient_p(struct sKhepera3SensorsInfrared *result);
int khepera3_infrared_proximity();
int khepera3_infrared_proximity_p(struct sKhepera3SensorsInfrared *result);
// Ultrasound sensors
enum eKhepera3SensorsUltrasound {
cKhepera3SensorsUltrasound_Left = 0,
cKhepera3SensorsUltrasound_FrontLeft = 1,
cKhepera3SensorsUltrasound_Front = 2,
cKhepera3SensorsUltrasound_FrontRight = 3,
cKhepera3SensorsUltrasound_Right = 4,
cKhepera3SensorsUltrasound_Begin = 0,
cKhepera3SensorsUltrasound_End = 5,
cKhepera3SensorsUltrasound_Count = 5
};
// Ultrasound sensor bit masks
enum eKhepera3SensorsUltrasoundBit {
cKhepera3SensorsUltrasoundBit_Left = 1,
cKhepera3SensorsUltrasoundBit_FrontLeft = 2,
cKhepera3SensorsUltrasoundBit_Front = 4,
cKhepera3SensorsUltrasoundBit_FrontRight = 8,
cKhepera3SensorsUltrasoundBit_Right = 16
cKhepera3SensorsUltrasoundBit_None = 0,
cKhepera3SensorsUltrasoundBit_All = 31,
};
// Functions
int khepera3_ultrasound(enum eKhepera3SensorsUltrasound sensor);
int khepera3_ultrasound_p(struct sKhepera3SensorsUltrasoundSensor *result, enum eKhepera3SensorsUltrasound sensor);
int khepera3_ultrasound_enable(enum eKhepera3SensorsUltrasoundBit bitmask);
int khepera3_ultrasound_set_max_echo_number(int max_echo_number);
enum eKhepera3SensorsUltrasound khepera3_ultrasound_getsensorbyname(const char *name, enum eKhepera3SensorsUltrasound defaultvalue);
enum eKhepera3SensorsUltrasoundBit khepera3_ultrasound_getsensorbitbysensor(enum eKhepera3SensorsUltrasound sensor);
// Functions
int khepera3_battery_voltage();
int khepera3_battery_current();
int khepera3_battery_current_average();
int khepera3_battery_capacity_remaining_absolute();
int khepera3_battery_capacity_remaining_relative();
int khepera3_battery_temperature();