| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- #include "payload.h"
- #include "control_rate.h"
- #include "dcm.h"
- #include "helpler_funtions.h"
- #include "quaternion.h"
- #include "soft_imu.h"
- /**
- * @brief 载荷控制指令
- *
- * @param ctl_ops_id 控制 id
- * @param arg 指令参数
- * @param arg_len 指令参数字节数
- * @param payload 载荷对象
- */
- void payload_ctl_received(uint8_t ctl_ops_id, const void *arg, uint32_t arg_len,
- struct payload_diaocang *payload)
- {
- switch (ctl_ops_id)
- {
- case PAYLOAD_DIAOCANG_OPS_BACK_MID:
- if (payload->_ops._return_to_mid)
- {
- payload->_ops._return_to_mid(payload->_ops._send_data);
- }
- break;
- case PAYLOAD_DIAOCANG_OPS_SET_PITCH:
- if (payload->_ops._set_pitch)
- {
- const int16_t *param = (const int16_t *)arg;
- payload->_ops._set_pitch(param[0] * 0.1f, payload->_ops._send_data);
- }
- break;
- case PAYLOAD_DIAOCANG_OPS_SET_YAW:
- if (payload->_ops._set_yaw)
- {
- const int16_t *param = (const int16_t *)arg;
- payload->_ops._set_yaw(param[0] * 0.1f, payload->_ops._send_data);
- }
- break;
- case PAYLOAD_DIAOCANG_OPS_LASER_MEASURE:
- if (payload->_ops._laser_dist)
- {
- payload->_ops._laser_dist(payload->_ops._send_data);
- }
- break;
- case PAYLOAD_DIAOCANG_OPS_TAKE_PHOTO:
- if (payload->_ops._take_photo)
- {
- payload->_ops._take_photo(payload->_ops._send_data);
- }
- break;
- case PAYLOAD_DIAOCANG_OPS_TAKE_VEDIO:
- if (payload->_ops._take_vedio)
- {
- const uint16_t *param = (const uint16_t *)arg;
- payload->_ops._take_vedio(param[0], payload->_ops._send_data);
- }
- break;
- case PAYLOAD_DIAOCANG_OPS_MOVE:
- if (payload->_ops._move)
- {
- const uint16_t *param = (const uint16_t *)arg;
- payload->_ops._move(param[0], param[1] * 0.001f,
- payload->_ops._send_data);
- }
- break;
- case PAYLOAD_DIAOCANG_OPS_TOUCH_MOVE:
- if (payload->_ops._touch_move)
- {
- const uint16_t *param = (const uint16_t *)arg;
- payload->_ops._touch_move(param[0] * 0.001f, param[1] * 0.001f,
- payload->_ops._send_data);
- }
- break;
- case PAYLOAD_DIAOCANG_OPS_ZOOM:
- if (payload->_ops._zoom)
- {
- const uint16_t *param = (const uint16_t *)arg;
- payload->_ops._zoom(param[0], param[1] * 0.001f,
- payload->_ops._send_data);
- }
- break;
- case PAYLOAD_DIAOCANG_OPS_TAR_TRACE:
- if (payload->_ops._trace)
- {
- const uint16_t *param = (const uint16_t *)arg;
- payload->_ops._trace(param[5], param[0] * 0.001f, param[1] * 0.001f,
- param[2] * 0.001f, param[3] * 0.001f,
- payload->_ops._send_data);
- }
- break;
- case PAYLOAD_DIAOCANG_OPS_FOCUS:
- if (payload->_ops._focus)
- {
- const uint32_t *param = (const uint32_t *)arg;
- payload->_ops._focus(param[0], param[1], param[2],
- payload->_ops._send_data);
- }
- break;
- case PAYLOAD_DIAOCANG_OPS_OSD_SET:
- break;
- case PAYLOAD_DIAOCANG_OPS_SENSOR_SWITCH:
- if (payload->_ops._sensor_switch)
- {
- const uint32_t *param = (const uint32_t *)arg;
- payload->_ops._sensor_switch(payload->_ops._send_data, param[0]);
- }
- break;
- case PAYLOAD_DIAOCANG_OPS_FOLLOW:
- if (payload->_ops._follow_mode)
- {
- payload->_ops._follow_mode(payload->_ops._send_data);
- }
- break;
- case PAYLOAD_DIAOCANG_OPS_LOOK_DOWN:
- if (payload->_ops._look_downward)
- {
- payload->_ops._look_downward(payload->_ops._send_data);
- }
- break;
- case PAYLOAD_DIAOCANG_OPS_LOCK:
- if (payload->_ops._lock_mode)
- {
- payload->_ops._lock_mode(payload->_ops._send_data);
- }
- break;
- case PAYLOAD_DIAOCANG_OPS_TTRANS:
- if (payload->_ops._send_data)
- {
- payload->_ops._send_data(arg, arg_len);
- }
- break;
- default:
- break;
- }
- }
- /**
- * @brief 载荷发送轮询
- *
- * @param tiem_us 当前本地时间 us
- * @param payload 载荷对象
- */
- void payload_tx_poll(uint32_t tiem_us, struct payload_diaocang *payload)
- {
- if (payload->_ops._tx_poll)
- {
- payload->_ops._tx_poll(tiem_us, &payload->_last_tx_time,
- payload->_ops._send_data);
- }
- }
- /**
- * @brief 载荷接收回调
- *
- * @param ch 接收到的字节数据
- * @param payload 载荷对象
- * @return int 暂无意义
- */
- int payload_rx_cbk(uint8_t ch, struct payload_diaocang *payload)
- {
- int ret = 0;
- if (payload->_ops._rx_cbk)
- {
- ret = payload->_ops._rx_cbk(ch, payload);
- }
- if (ret > 0)
- {
- payload->_link_lost_count = 0;
- payload->_link_status = COMP_NORMAL;
- }
- return ret;
- }
- /**
- * @brief 载荷链接状态轮询
- *
- * @param time_now_us
- * @param payload
- */
- void payload_check_linkstatu_poll(uint32_t time_now_us,
- struct payload_diaocang *payload)
- {
- const float dt = 0.2f;
- const float link_lost_time_period = 3.0f;
- if (time_now_us - payload->_link_check_time > dt * 1000000)
- {
- if (payload->_link_status == COMP_NORMAL)
- {
- payload->_link_check_time = time_now_us;
- payload->_link_lost_count++;
- if (payload->_link_lost_count * dt > link_lost_time_period)
- {
- payload->_link_lost_count = 0;
- payload->_link_status = COMP_LOST;
- }
- }
- }
- }
- /**
- * @brief 光电吊舱类载荷目标定位
- *
- * @param payload 载荷对象
- * @param gimbal_euler_frame 载荷角度类型 0-相对载具平台 1-相对导航水平平台
- */
- static int _gimbal_pod_payload_target_locate(struct payload_diaocang *payload,
- uint8_t gimbal_euler_frame)
- {
- if (payload->_link_status == COMP_NORMAL && payload->_status.trace_flag &&
- ins.insgps_ok == INSGPS)
- {
- // camera->ENU
- float qCN[4] = {1, 0, 0, 0};
- if (gimbal_euler_frame == 0)
- {
- // body->ENU
- float qbN[4];
- for (int i = 0; i < 4; ++i)
- {
- qbN[i] = ins.Q[i];
- }
- // camera->body
- float qCb[4] = {1, 0, 0, 0};
- float qtmp1[4], qtmp2[4], qtmp3[4], qtmp4[4];
- // gimbal frame sequence is yaw->roll->pitch, which is different from
- // body euler angle sequence
- Quaternion_ByEuler(deg_to_rad(-payload->_status.yaw), 0, 0, qtmp1);
- Quaternion_ByEuler(0, 0, deg_to_rad(payload->_status.roll), qtmp2);
- Quaternion_ByEuler(0, deg_to_rad(payload->_status.pitch), 0, qtmp3);
- Quaternion_Multiplication(qtmp1, qtmp2, qtmp4);
- Quaternion_Normalize(qtmp4);
- Quaternion_Multiplication(qtmp4, qtmp3, qCb);
- Quaternion_Normalize(qCb);
- // camera->ENU
- Quaternion_Multiplication(qbN, qCb, qCN);
- Quaternion_Normalize(qCN);
- }
- else if (gimbal_euler_frame == 1)
- {
- Quaternion_ByEuler(
- deg_to_rad(-payload->_status.yaw - pid_m_yaw.angle_c),
- deg_to_rad(payload->_status.pitch),
- deg_to_rad(payload->_status.roll), qCN);
- }
- // calculate camera y axis coordinate in NEU frame
- float v[3] = {0, 1, 0};
- Quaternion_Conj(qCN, v, payload->_status.y_axis);
- // 根据载荷光轴的向量和载荷的相对高度,计算载荷的光轴和地面交点向量在地面的投影
- float k1 = 0.0f;
- float payloadAlt = pid_m_alt.loc_c;
- if (fabsf(payload->_status.y_axis[2]) < 0.001f)
- {
- k1 = payloadAlt / 0.001f;
- }
- else
- {
- k1 = payloadAlt / fabsf(payload->_status.y_axis[2]);
- }
- payload->_diste_filter_buffer[payload->_filter_in_index] =
- payload->_status.y_axis[0] * k1;
- payload->_distn_filter_buffer[payload->_filter_in_index] =
- payload->_status.y_axis[1] * k1;
- payload->_filter_in_index++;
- if (payload->_filter_in_index >= PAYLOAD_SZHT_FILTER_BUFF_LEN)
- payload->_filter_in_index = 0;
- float dist_e = 0;
- float dist_n = 0;
- for (int i = 0; i < PAYLOAD_SZHT_FILTER_BUFF_LEN; ++i)
- {
- dist_e +=
- payload->_diste_filter_buffer[i] / PAYLOAD_SZHT_FILTER_BUFF_LEN;
- dist_n +=
- payload->_distn_filter_buffer[i] / PAYLOAD_SZHT_FILTER_BUFF_LEN;
- }
- payload->_status.tar_lon =
- pid_m_posx.loc_c + dist_e / ins.delta_lon_to_cm_ratio;
- payload->_status.tar_lat =
- pid_m_posy.loc_c + dist_n / ins.delta_lat_to_cm_ratio;
- payload->_status.tar_alt = 0;
- payload->_status.tar_lon_loc =
- pid_m_posx.loc_c +
- payload->_status.y_axis[0] * payload->_status.laser_dist_m * 100 / ins.delta_lon_to_cm_ratio;
- payload->_status.tar_lat_loc =
- pid_m_posy.loc_c +
- payload->_status.y_axis[1] * payload->_status.laser_dist_m * 100 / ins.delta_lat_to_cm_ratio;
- payload->_status.tar_alt_loc = 0;
- return 0;
- }
- return -1;
- }
- /**
- * @brief 载荷目标定位
- *
- * @param payload
- */
- void payload_targte_locate(struct payload_diaocang *payload, uint8_t gimbal_euler_frame)
- {
- if (payload->_type == PAYLOAD_TYPE_GIMBAL_POD)
- {
- _gimbal_pod_payload_target_locate(payload, gimbal_euler_frame);
- }
- }
|