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();