|
|
@ -531,6 +531,123 @@ CollisionPrevention::modifySetpoint(Vector2f &original_setpoint, const float max |
|
|
|
original_setpoint = new_setpoint; |
|
|
|
original_setpoint = new_setpoint; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
|
|
|
CollisionPrevention::modifySetpointH(float &original_setpoint, const float max_speed, const float &curr_pos, |
|
|
|
|
|
|
|
const float &curr_vel) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
//calculate movement constraints based on range data
|
|
|
|
|
|
|
|
float setpoint = original_setpoint; |
|
|
|
|
|
|
|
/******************************************************************/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// _calculateConstrainedSetpoint(new_setpoint, curr_pos, curr_vel);
|
|
|
|
|
|
|
|
// read parameters
|
|
|
|
|
|
|
|
static float min_distance; |
|
|
|
|
|
|
|
static float max_distance; |
|
|
|
|
|
|
|
static float up_distance; |
|
|
|
|
|
|
|
static uint64_t _data_h_timestamps; |
|
|
|
|
|
|
|
static uint64_t _dist_timestamps; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 获取测距距离值相关
|
|
|
|
|
|
|
|
for (auto &dist_sens_sub : _distance_sensor_subs) { |
|
|
|
|
|
|
|
distance_sensor_s distance_sensor; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (dist_sens_sub.update(&distance_sensor)) { |
|
|
|
|
|
|
|
// consider only instances with valid data and orientations useful for collision prevention
|
|
|
|
|
|
|
|
// 距离值有效,并且是朝上的距离
|
|
|
|
|
|
|
|
if ((getElapsedTime(&distance_sensor.timestamp) < RANGE_STREAM_TIMEOUT_US) && |
|
|
|
|
|
|
|
(distance_sensor.orientation == distance_sensor_s::ROTATION_UPWARD_FACING)) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// update message description
|
|
|
|
|
|
|
|
_dist_timestamps = distance_sensor.timestamp; |
|
|
|
|
|
|
|
max_distance = math::max(max_distance,(distance_sensor.max_distance )); |
|
|
|
|
|
|
|
min_distance = math::min(min_distance,(distance_sensor.min_distance )); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
up_distance = distance_sensor.current_distance; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// 获取一些参数设置
|
|
|
|
|
|
|
|
const float col_prev_d = _param_cp_dist.get(); |
|
|
|
|
|
|
|
const float col_prev_dly = _param_cp_delay.get(); |
|
|
|
|
|
|
|
const bool move_no_data = _param_cp_go_nodata.get(); |
|
|
|
|
|
|
|
const float xy_p = _param_mpc_xy_p.get(); |
|
|
|
|
|
|
|
const float max_jerk = _param_mpc_jerk_max.get(); |
|
|
|
|
|
|
|
const float max_accel = _param_mpc_acc_hor.get(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const float setpoint_length = setpoint; |
|
|
|
|
|
|
|
const hrt_abstime constrain_time = getTime(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((constrain_time - _dist_timestamps) < RANGE_STREAM_TIMEOUT_US) { |
|
|
|
|
|
|
|
if (setpoint_length > 0.001f) { |
|
|
|
|
|
|
|
float vel_max = setpoint_length; |
|
|
|
|
|
|
|
// 最小停留距离,测距最小值或者参数设置停留值
|
|
|
|
|
|
|
|
const float min_dist_to_keep = math::max(min_distance / 100.0f, col_prev_d); |
|
|
|
|
|
|
|
// 删除过时的值
|
|
|
|
|
|
|
|
const hrt_abstime data_age = constrain_time - _data_h_timestamps;//TODO: _data_timestamps需要赋值
|
|
|
|
|
|
|
|
if (data_age > RANGE_STREAM_TIMEOUT_US) { |
|
|
|
|
|
|
|
up_distance = UINT16_MAX * 0.01f; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
const float distance = up_distance; |
|
|
|
|
|
|
|
const float max_range = max_distance + 0.005f; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (distance > _obstacle_map_body_frame.min_distance && distance < UINT16_MAX * 0.01f) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// calculate max allowed velocity with a P-controller (same gain as in the position controller)
|
|
|
|
|
|
|
|
const float curr_vel_parallel = math::max(0.f, curr_vel); |
|
|
|
|
|
|
|
float delay_distance = curr_vel_parallel * col_prev_dly; |
|
|
|
|
|
|
|
if (distance < max_range) { |
|
|
|
|
|
|
|
delay_distance += curr_vel_parallel * (data_age * 1e-6f); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
const float stop_distance = math::max(0.f, distance - min_dist_to_keep - delay_distance); |
|
|
|
|
|
|
|
const float vel_max_posctrl = xy_p * stop_distance; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const float vel_max_smooth = math::trajectory::computeMaxSpeedFromDistance(max_jerk, max_accel, stop_distance, 0.f); |
|
|
|
|
|
|
|
float vel_max_bin = math::min(vel_max_posctrl, vel_max_smooth) ; |
|
|
|
|
|
|
|
// constrain the velocity
|
|
|
|
|
|
|
|
if (vel_max_bin >= 0) { |
|
|
|
|
|
|
|
vel_max = math::min(vel_max, vel_max_bin); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}else if (distance >= UINT16_MAX * 0.01f ) { |
|
|
|
|
|
|
|
if (!move_no_data || (move_no_data)) { |
|
|
|
|
|
|
|
vel_max = 0.f; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setpoint = vel_max; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
//allow no movement
|
|
|
|
|
|
|
|
float vel_max = 0.f; |
|
|
|
|
|
|
|
setpoint = setpoint * vel_max; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if distance data is stale, switch to Loiter
|
|
|
|
|
|
|
|
if (getElapsedTime(&_last_timeout_warning) > 1_s && getElapsedTime(&_time_activated) > 1_s) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((constrain_time - _dist_timestamps) > TIMEOUT_HOLD_US |
|
|
|
|
|
|
|
&& getElapsedTime(&_time_activated) > TIMEOUT_HOLD_US) { |
|
|
|
|
|
|
|
_publishVehicleCmdDoLoiter(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_last_timeout_warning = getTime(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_data_h_timestamps = getTime(); |
|
|
|
|
|
|
|
/******************************************************************/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//warn user if collision prevention starts to interfere
|
|
|
|
|
|
|
|
bool currently_interfering = (setpoint < original_setpoint - 0.05f * max_speed |
|
|
|
|
|
|
|
|| setpoint > original_setpoint + 0.05f * max_speed); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_interfering = currently_interfering; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
original_setpoint = setpoint; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void CollisionPrevention::_publishVehicleCmdDoLoiter() |
|
|
|
void CollisionPrevention::_publishVehicleCmdDoLoiter() |
|
|
|
{ |
|
|
|
{ |
|
|
|
vehicle_command_s command{}; |
|
|
|
vehicle_command_s command{}; |
|
|
|