parent
							
								
									11889f4870
								
							
						
					
					
						commit
						3377f74eca
					
				
				 4 changed files with 2 additions and 588 deletions
			
			
		| @ -1,330 +0,0 @@ | ||||
| #include "selfdrive/modeld/models/driving.h" | ||||
| 
 | ||||
| #include <cstring> | ||||
| 
 | ||||
| 
 | ||||
| void fill_lead(cereal::ModelDataV2::LeadDataV3::Builder lead, const ModelOutputLeads &leads, int t_idx, float prob_t) { | ||||
|   std::array<float, LEAD_TRAJ_LEN> lead_t = {0.0, 2.0, 4.0, 6.0, 8.0, 10.0}; | ||||
|   const auto &best_prediction = leads.get_best_prediction(t_idx); | ||||
|   lead.setProb(sigmoid(leads.prob[t_idx])); | ||||
|   lead.setProbTime(prob_t); | ||||
|   std::array<float, LEAD_TRAJ_LEN> lead_x, lead_y, lead_v, lead_a; | ||||
|   std::array<float, LEAD_TRAJ_LEN> lead_x_std, lead_y_std, lead_v_std, lead_a_std; | ||||
|   for (int i=0; i<LEAD_TRAJ_LEN; i++) { | ||||
|     lead_x[i] = best_prediction.mean[i].x; | ||||
|     lead_y[i] = best_prediction.mean[i].y; | ||||
|     lead_v[i] = best_prediction.mean[i].velocity; | ||||
|     lead_a[i] = best_prediction.mean[i].acceleration; | ||||
|     lead_x_std[i] = exp(best_prediction.std[i].x); | ||||
|     lead_y_std[i] = exp(best_prediction.std[i].y); | ||||
|     lead_v_std[i] = exp(best_prediction.std[i].velocity); | ||||
|     lead_a_std[i] = exp(best_prediction.std[i].acceleration); | ||||
|   } | ||||
|   lead.setT(to_kj_array_ptr(lead_t)); | ||||
|   lead.setX(to_kj_array_ptr(lead_x)); | ||||
|   lead.setY(to_kj_array_ptr(lead_y)); | ||||
|   lead.setV(to_kj_array_ptr(lead_v)); | ||||
|   lead.setA(to_kj_array_ptr(lead_a)); | ||||
|   lead.setXStd(to_kj_array_ptr(lead_x_std)); | ||||
|   lead.setYStd(to_kj_array_ptr(lead_y_std)); | ||||
|   lead.setVStd(to_kj_array_ptr(lead_v_std)); | ||||
|   lead.setAStd(to_kj_array_ptr(lead_a_std)); | ||||
| } | ||||
| 
 | ||||
| void fill_meta(cereal::ModelDataV2::MetaData::Builder meta, const ModelOutputMeta &meta_data, PublishState &ps) { | ||||
|   std::array<float, DESIRE_LEN> desire_state_softmax; | ||||
|   softmax(meta_data.desire_state_prob.array.data(), desire_state_softmax.data(), DESIRE_LEN); | ||||
| 
 | ||||
|   std::array<float, DESIRE_PRED_LEN * DESIRE_LEN> desire_pred_softmax; | ||||
|   for (int i=0; i<DESIRE_PRED_LEN; i++) { | ||||
|     softmax(meta_data.desire_pred_prob[i].array.data(), desire_pred_softmax.data() + (i * DESIRE_LEN), DESIRE_LEN); | ||||
|   } | ||||
| 
 | ||||
|   std::array<float, DISENGAGE_LEN> lat_long_t = {2, 4, 6, 8, 10}; | ||||
|   std::array<float, DISENGAGE_LEN> gas_disengage_sigmoid, brake_disengage_sigmoid, steer_override_sigmoid, | ||||
|                                    brake_3ms2_sigmoid, brake_4ms2_sigmoid, brake_5ms2_sigmoid; | ||||
|   for (int i=0; i<DISENGAGE_LEN; i++) { | ||||
|     gas_disengage_sigmoid[i] = sigmoid(meta_data.disengage_prob[i].gas_disengage); | ||||
|     brake_disengage_sigmoid[i] = sigmoid(meta_data.disengage_prob[i].brake_disengage); | ||||
|     steer_override_sigmoid[i] = sigmoid(meta_data.disengage_prob[i].steer_override); | ||||
|     brake_3ms2_sigmoid[i] = sigmoid(meta_data.disengage_prob[i].brake_3ms2); | ||||
|     brake_4ms2_sigmoid[i] = sigmoid(meta_data.disengage_prob[i].brake_4ms2); | ||||
|     brake_5ms2_sigmoid[i] = sigmoid(meta_data.disengage_prob[i].brake_5ms2); | ||||
|     //gas_pressed_sigmoid[i] = sigmoid(meta_data.disengage_prob[i].gas_pressed);
 | ||||
|   } | ||||
| 
 | ||||
|   std::memmove(ps.prev_brake_5ms2_probs.data(), &ps.prev_brake_5ms2_probs[1], 4*sizeof(float)); | ||||
|   std::memmove(ps.prev_brake_3ms2_probs.data(), &ps.prev_brake_3ms2_probs[1], 2*sizeof(float)); | ||||
|   ps.prev_brake_5ms2_probs[4] = brake_5ms2_sigmoid[0]; | ||||
|   ps.prev_brake_3ms2_probs[2] = brake_3ms2_sigmoid[0]; | ||||
| 
 | ||||
|   bool above_fcw_threshold = true; | ||||
|   for (int i=0; i<ps.prev_brake_5ms2_probs.size(); i++) { | ||||
|     float threshold = i < 2 ? FCW_THRESHOLD_5MS2_LOW : FCW_THRESHOLD_5MS2_HIGH; | ||||
|     above_fcw_threshold = above_fcw_threshold && ps.prev_brake_5ms2_probs[i] > threshold; | ||||
|   } | ||||
|   for (int i=0; i<ps.prev_brake_3ms2_probs.size(); i++) { | ||||
|     above_fcw_threshold = above_fcw_threshold && ps.prev_brake_3ms2_probs[i] > FCW_THRESHOLD_3MS2; | ||||
|   } | ||||
| 
 | ||||
|   auto disengage = meta.initDisengagePredictions(); | ||||
|   disengage.setT(to_kj_array_ptr(lat_long_t)); | ||||
|   disengage.setGasDisengageProbs(to_kj_array_ptr(gas_disengage_sigmoid)); | ||||
|   disengage.setBrakeDisengageProbs(to_kj_array_ptr(brake_disengage_sigmoid)); | ||||
|   disengage.setSteerOverrideProbs(to_kj_array_ptr(steer_override_sigmoid)); | ||||
|   disengage.setBrake3MetersPerSecondSquaredProbs(to_kj_array_ptr(brake_3ms2_sigmoid)); | ||||
|   disengage.setBrake4MetersPerSecondSquaredProbs(to_kj_array_ptr(brake_4ms2_sigmoid)); | ||||
|   disengage.setBrake5MetersPerSecondSquaredProbs(to_kj_array_ptr(brake_5ms2_sigmoid)); | ||||
| 
 | ||||
|   meta.setEngagedProb(sigmoid(meta_data.engaged_prob)); | ||||
|   meta.setDesirePrediction(to_kj_array_ptr(desire_pred_softmax)); | ||||
|   meta.setDesireState(to_kj_array_ptr(desire_state_softmax)); | ||||
|   meta.setHardBrakePredicted(above_fcw_threshold); | ||||
| } | ||||
| 
 | ||||
| void fill_confidence(cereal::ModelDataV2::Builder &framed, PublishState &ps) { | ||||
|   if (framed.getFrameId() % (2*MODEL_FREQ) == 0) { | ||||
|     // update every 2s to match predictions interval
 | ||||
|     auto dbps = framed.getMeta().getDisengagePredictions().getBrakeDisengageProbs(); | ||||
|     auto dgps = framed.getMeta().getDisengagePredictions().getGasDisengageProbs(); | ||||
|     auto dsps = framed.getMeta().getDisengagePredictions().getSteerOverrideProbs(); | ||||
| 
 | ||||
|     float any_dp[DISENGAGE_LEN]; | ||||
|     float dp_ind[DISENGAGE_LEN]; | ||||
| 
 | ||||
|     for (int i = 0; i < DISENGAGE_LEN; i++) { | ||||
|       any_dp[i] = 1 - ((1-dbps[i])*(1-dgps[i])*(1-dsps[i])); // any disengage prob
 | ||||
|     } | ||||
| 
 | ||||
|     dp_ind[0] = any_dp[0]; | ||||
|     for (int i = 0; i < DISENGAGE_LEN-1; i++) { | ||||
|       dp_ind[i+1] = (any_dp[i+1] - any_dp[i]) / (1 - any_dp[i]); // independent disengage prob for each 2s slice
 | ||||
|     } | ||||
| 
 | ||||
|     // rolling buf for 2, 4, 6, 8, 10s
 | ||||
|     std::memmove(&ps.disengage_buffer[0], &ps.disengage_buffer[DISENGAGE_LEN], sizeof(float) * DISENGAGE_LEN * (DISENGAGE_LEN-1)); | ||||
|     std::memcpy(&ps.disengage_buffer[DISENGAGE_LEN * (DISENGAGE_LEN-1)], &dp_ind[0], sizeof(float) * DISENGAGE_LEN); | ||||
|   } | ||||
| 
 | ||||
|   float score = 0; | ||||
|   for (int i = 0; i < DISENGAGE_LEN; i++) { | ||||
|     score += ps.disengage_buffer[i*DISENGAGE_LEN+DISENGAGE_LEN-1-i] / DISENGAGE_LEN; | ||||
|   } | ||||
| 
 | ||||
|   if (score < RYG_GREEN) { | ||||
|     framed.setConfidence(cereal::ModelDataV2::ConfidenceClass::GREEN); | ||||
|   } else if (score < RYG_YELLOW) { | ||||
|     framed.setConfidence(cereal::ModelDataV2::ConfidenceClass::YELLOW); | ||||
|   } else { | ||||
|     framed.setConfidence(cereal::ModelDataV2::ConfidenceClass::RED); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| template<size_t size> | ||||
| void fill_xyzt(cereal::XYZTData::Builder xyzt, const std::array<float, size> &t, | ||||
|                const std::array<float, size> &x, const std::array<float, size> &y, const std::array<float, size> &z) { | ||||
|   xyzt.setT(to_kj_array_ptr(t)); | ||||
|   xyzt.setX(to_kj_array_ptr(x)); | ||||
|   xyzt.setY(to_kj_array_ptr(y)); | ||||
|   xyzt.setZ(to_kj_array_ptr(z)); | ||||
| } | ||||
| 
 | ||||
| template<size_t size> | ||||
| void fill_xyzt(cereal::XYZTData::Builder xyzt, const std::array<float, size> &t, | ||||
|                const std::array<float, size> &x, const std::array<float, size> &y, const std::array<float, size> &z, | ||||
|                const std::array<float, size> &x_std, const std::array<float, size> &y_std, const std::array<float, size> &z_std) { | ||||
|   fill_xyzt(xyzt, t, x, y, z); | ||||
|   xyzt.setXStd(to_kj_array_ptr(x_std)); | ||||
|   xyzt.setYStd(to_kj_array_ptr(y_std)); | ||||
|   xyzt.setZStd(to_kj_array_ptr(z_std)); | ||||
| } | ||||
| 
 | ||||
| void fill_plan(cereal::ModelDataV2::Builder &framed, const ModelOutputPlanPrediction &plan) { | ||||
|   std::array<float, TRAJECTORY_SIZE> pos_x, pos_y, pos_z; | ||||
|   std::array<float, TRAJECTORY_SIZE> pos_x_std, pos_y_std, pos_z_std; | ||||
|   std::array<float, TRAJECTORY_SIZE> vel_x, vel_y, vel_z; | ||||
|   std::array<float, TRAJECTORY_SIZE> rot_x, rot_y, rot_z; | ||||
|   std::array<float, TRAJECTORY_SIZE> acc_x, acc_y, acc_z; | ||||
|   std::array<float, TRAJECTORY_SIZE> rot_rate_x, rot_rate_y, rot_rate_z; | ||||
| 
 | ||||
|   for (int i=0; i<TRAJECTORY_SIZE; i++) { | ||||
|     pos_x[i] = plan.mean[i].position.x; | ||||
|     pos_y[i] = plan.mean[i].position.y; | ||||
|     pos_z[i] = plan.mean[i].position.z; | ||||
|     pos_x_std[i] = exp(plan.std[i].position.x); | ||||
|     pos_y_std[i] = exp(plan.std[i].position.y); | ||||
|     pos_z_std[i] = exp(plan.std[i].position.z); | ||||
|     vel_x[i] = plan.mean[i].velocity.x; | ||||
|     vel_y[i] = plan.mean[i].velocity.y; | ||||
|     vel_z[i] = plan.mean[i].velocity.z; | ||||
|     acc_x[i] = plan.mean[i].acceleration.x; | ||||
|     acc_y[i] = plan.mean[i].acceleration.y; | ||||
|     acc_z[i] = plan.mean[i].acceleration.z; | ||||
|     rot_x[i] = plan.mean[i].rotation.x; | ||||
|     rot_y[i] = plan.mean[i].rotation.y; | ||||
|     rot_z[i] = plan.mean[i].rotation.z; | ||||
|     rot_rate_x[i] = plan.mean[i].rotation_rate.x; | ||||
|     rot_rate_y[i] = plan.mean[i].rotation_rate.y; | ||||
|     rot_rate_z[i] = plan.mean[i].rotation_rate.z; | ||||
|   } | ||||
| 
 | ||||
|   fill_xyzt(framed.initPosition(), T_IDXS_FLOAT, pos_x, pos_y, pos_z, pos_x_std, pos_y_std, pos_z_std); | ||||
|   fill_xyzt(framed.initVelocity(), T_IDXS_FLOAT, vel_x, vel_y, vel_z); | ||||
|   fill_xyzt(framed.initAcceleration(), T_IDXS_FLOAT, acc_x, acc_y, acc_z); | ||||
|   fill_xyzt(framed.initOrientation(), T_IDXS_FLOAT, rot_x, rot_y, rot_z); | ||||
|   fill_xyzt(framed.initOrientationRate(), T_IDXS_FLOAT, rot_rate_x, rot_rate_y, rot_rate_z); | ||||
| } | ||||
| 
 | ||||
| void fill_lane_lines(cereal::ModelDataV2::Builder &framed, const std::array<float, TRAJECTORY_SIZE> &plan_t, | ||||
|                      const ModelOutputLaneLines &lanes) { | ||||
|   std::array<float, TRAJECTORY_SIZE> left_far_y, left_far_z; | ||||
|   std::array<float, TRAJECTORY_SIZE> left_near_y, left_near_z; | ||||
|   std::array<float, TRAJECTORY_SIZE> right_near_y, right_near_z; | ||||
|   std::array<float, TRAJECTORY_SIZE> right_far_y, right_far_z; | ||||
|   for (int j=0; j<TRAJECTORY_SIZE; j++) { | ||||
|     left_far_y[j] = lanes.mean.left_far[j].y; | ||||
|     left_far_z[j] = lanes.mean.left_far[j].z; | ||||
|     left_near_y[j] = lanes.mean.left_near[j].y; | ||||
|     left_near_z[j] = lanes.mean.left_near[j].z; | ||||
|     right_near_y[j] = lanes.mean.right_near[j].y; | ||||
|     right_near_z[j] = lanes.mean.right_near[j].z; | ||||
|     right_far_y[j] = lanes.mean.right_far[j].y; | ||||
|     right_far_z[j] = lanes.mean.right_far[j].z; | ||||
|   } | ||||
| 
 | ||||
|   auto lane_lines = framed.initLaneLines(4); | ||||
|   fill_xyzt(lane_lines[0], plan_t, X_IDXS_FLOAT, left_far_y, left_far_z); | ||||
|   fill_xyzt(lane_lines[1], plan_t, X_IDXS_FLOAT, left_near_y, left_near_z); | ||||
|   fill_xyzt(lane_lines[2], plan_t, X_IDXS_FLOAT, right_near_y, right_near_z); | ||||
|   fill_xyzt(lane_lines[3], plan_t, X_IDXS_FLOAT, right_far_y, right_far_z); | ||||
| 
 | ||||
|   framed.setLaneLineStds({ | ||||
|     exp(lanes.std.left_far[0].y), | ||||
|     exp(lanes.std.left_near[0].y), | ||||
|     exp(lanes.std.right_near[0].y), | ||||
|     exp(lanes.std.right_far[0].y), | ||||
|   }); | ||||
| 
 | ||||
|   framed.setLaneLineProbs({ | ||||
|     sigmoid(lanes.prob.left_far.val), | ||||
|     sigmoid(lanes.prob.left_near.val), | ||||
|     sigmoid(lanes.prob.right_near.val), | ||||
|     sigmoid(lanes.prob.right_far.val), | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| void fill_road_edges(cereal::ModelDataV2::Builder &framed, const std::array<float, TRAJECTORY_SIZE> &plan_t, | ||||
|                      const ModelOutputRoadEdges &edges) { | ||||
|   std::array<float, TRAJECTORY_SIZE> left_y, left_z; | ||||
|   std::array<float, TRAJECTORY_SIZE> right_y, right_z; | ||||
|   for (int j=0; j<TRAJECTORY_SIZE; j++) { | ||||
|     left_y[j] = edges.mean.left[j].y; | ||||
|     left_z[j] = edges.mean.left[j].z; | ||||
|     right_y[j] = edges.mean.right[j].y; | ||||
|     right_z[j] = edges.mean.right[j].z; | ||||
|   } | ||||
| 
 | ||||
|   auto road_edges = framed.initRoadEdges(2); | ||||
|   fill_xyzt(road_edges[0], plan_t, X_IDXS_FLOAT, left_y, left_z); | ||||
|   fill_xyzt(road_edges[1], plan_t, X_IDXS_FLOAT, right_y, right_z); | ||||
| 
 | ||||
|   framed.setRoadEdgeStds({ | ||||
|     exp(edges.std.left[0].y), | ||||
|     exp(edges.std.right[0].y), | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| void fill_model(cereal::ModelDataV2::Builder &framed, const ModelOutput &net_outputs, PublishState &ps) { | ||||
|   const auto &best_plan = net_outputs.plans.get_best_prediction(); | ||||
|   std::array<float, TRAJECTORY_SIZE> plan_t; | ||||
|   std::fill_n(plan_t.data(), plan_t.size(), NAN); | ||||
|   plan_t[0] = 0.0; | ||||
|   for (int xidx=1, tidx=0; xidx<TRAJECTORY_SIZE; xidx++) { | ||||
|     // increment tidx until we find an element that's further away than the current xidx
 | ||||
|     for (int next_tid = tidx + 1; next_tid < TRAJECTORY_SIZE && best_plan.mean[next_tid].position.x < X_IDXS[xidx]; next_tid++) { | ||||
|       tidx++; | ||||
|     } | ||||
|     if (tidx == TRAJECTORY_SIZE - 1) { | ||||
|       // if the Plan doesn't extend far enough, set plan_t to the max value (10s), then break
 | ||||
|       plan_t[xidx] = T_IDXS[TRAJECTORY_SIZE - 1]; | ||||
|       break; | ||||
|     } | ||||
| 
 | ||||
|     // interpolate to find `t` for the current xidx
 | ||||
|     float current_x_val = best_plan.mean[tidx].position.x; | ||||
|     float next_x_val = best_plan.mean[tidx+1].position.x; | ||||
|     float p = (X_IDXS[xidx] - current_x_val) / (next_x_val - current_x_val); | ||||
|     plan_t[xidx] = p * T_IDXS[tidx+1] + (1 - p) * T_IDXS[tidx]; | ||||
|   } | ||||
| 
 | ||||
|   fill_plan(framed, best_plan); | ||||
|   fill_lane_lines(framed, plan_t, net_outputs.lane_lines); | ||||
|   fill_road_edges(framed, plan_t, net_outputs.road_edges); | ||||
| 
 | ||||
|   // meta
 | ||||
|   fill_meta(framed.initMeta(), net_outputs.meta, ps); | ||||
| 
 | ||||
|   // confidence
 | ||||
|   fill_confidence(framed, ps); | ||||
| 
 | ||||
|   // leads
 | ||||
|   auto leads = framed.initLeadsV3(LEAD_MHP_SELECTION); | ||||
|   std::array<float, LEAD_MHP_SELECTION> t_offsets = {0.0, 2.0, 4.0}; | ||||
|   for (int i=0; i<LEAD_MHP_SELECTION; i++) { | ||||
|     fill_lead(leads[i], net_outputs.leads, i, t_offsets[i]); | ||||
|   } | ||||
| 
 | ||||
|   // temporal pose
 | ||||
|   const auto &v_mean = net_outputs.temporal_pose.velocity_mean; | ||||
|   const auto &r_mean = net_outputs.temporal_pose.rotation_mean; | ||||
|   const auto &v_std = net_outputs.temporal_pose.velocity_std; | ||||
|   const auto &r_std = net_outputs.temporal_pose.rotation_std; | ||||
|   auto temporal_pose = framed.initTemporalPose(); | ||||
|   temporal_pose.setTrans({v_mean.x, v_mean.y, v_mean.z}); | ||||
|   temporal_pose.setRot({r_mean.x, r_mean.y, r_mean.z}); | ||||
|   temporal_pose.setTransStd({exp(v_std.x), exp(v_std.y), exp(v_std.z)}); | ||||
|   temporal_pose.setRotStd({exp(r_std.x), exp(r_std.y), exp(r_std.z)}); | ||||
| } | ||||
| 
 | ||||
| void fill_model_msg(MessageBuilder &msg, float *net_output_data, PublishState &ps, uint32_t vipc_frame_id, uint32_t vipc_frame_id_extra, uint32_t frame_id, float frame_drop, | ||||
|                     uint64_t timestamp_eof, uint64_t timestamp_llk, float model_execution_time, const bool nav_enabled, const bool valid) { | ||||
|   const uint32_t frame_age = (frame_id > vipc_frame_id) ? (frame_id - vipc_frame_id) : 0; | ||||
|   auto framed = msg.initEvent(valid).initModelV2(); | ||||
|   framed.setFrameId(vipc_frame_id); | ||||
|   framed.setFrameIdExtra(vipc_frame_id_extra); | ||||
|   framed.setFrameAge(frame_age); | ||||
|   framed.setFrameDropPerc(frame_drop * 100); | ||||
|   framed.setTimestampEof(timestamp_eof); | ||||
|   framed.setLocationMonoTime(timestamp_llk); | ||||
|   framed.setModelExecutionTime(model_execution_time); | ||||
|   framed.setNavEnabled(nav_enabled); | ||||
|   if (send_raw_pred) { | ||||
|     framed.setRawPredictions(kj::ArrayPtr<const float>(net_output_data, NET_OUTPUT_SIZE).asBytes()); | ||||
|   } | ||||
|   fill_model(framed, *((ModelOutput*) net_output_data), ps); | ||||
| } | ||||
| 
 | ||||
| void fill_pose_msg(MessageBuilder &msg, float *net_output_data, uint32_t vipc_frame_id, uint32_t vipc_dropped_frames, uint64_t timestamp_eof, const bool valid) { | ||||
|     const ModelOutput &net_outputs = *((ModelOutput*) net_output_data); | ||||
|     const auto &v_mean = net_outputs.pose.velocity_mean; | ||||
|     const auto &r_mean = net_outputs.pose.rotation_mean; | ||||
|     const auto &t_mean = net_outputs.wide_from_device_euler.mean; | ||||
|     const auto &v_std = net_outputs.pose.velocity_std; | ||||
|     const auto &r_std = net_outputs.pose.rotation_std; | ||||
|     const auto &t_std = net_outputs.wide_from_device_euler.std; | ||||
|     const auto &road_transform_trans_mean = net_outputs.road_transform.position_mean; | ||||
|     const auto &road_transform_trans_std = net_outputs.road_transform.position_std; | ||||
| 
 | ||||
|     auto posenetd = msg.initEvent(valid && (vipc_dropped_frames < 1)).initCameraOdometry(); | ||||
|     posenetd.setTrans({v_mean.x, v_mean.y, v_mean.z}); | ||||
|     posenetd.setRot({r_mean.x, r_mean.y, r_mean.z}); | ||||
|     posenetd.setWideFromDeviceEuler({t_mean.x, t_mean.y, t_mean.z}); | ||||
|     posenetd.setRoadTransformTrans({road_transform_trans_mean.x, road_transform_trans_mean.y, road_transform_trans_mean.z}); | ||||
|     posenetd.setTransStd({exp(v_std.x), exp(v_std.y), exp(v_std.z)}); | ||||
|     posenetd.setRotStd({exp(r_std.x), exp(r_std.y), exp(r_std.z)}); | ||||
|     posenetd.setWideFromDeviceEulerStd({exp(t_std.x), exp(t_std.y), exp(t_std.z)}); | ||||
|     posenetd.setRoadTransformTransStd({exp(road_transform_trans_std.x), exp(road_transform_trans_std.y), exp(road_transform_trans_std.z)}); | ||||
| 
 | ||||
|     posenetd.setTimestampEof(timestamp_eof); | ||||
|     posenetd.setFrameId(vipc_frame_id); | ||||
| } | ||||
| @ -1,257 +0,0 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include <array> | ||||
| #include <memory> | ||||
| 
 | ||||
| #include "cereal/messaging/messaging.h" | ||||
| #include "common/modeldata.h" | ||||
| #include "common/util.h" | ||||
| #include "selfdrive/modeld/models/commonmodel.h" | ||||
| #include "selfdrive/modeld/runners/run.h" | ||||
| 
 | ||||
| constexpr int FEATURE_LEN = 512; | ||||
| constexpr int HISTORY_BUFFER_LEN = 99; | ||||
| constexpr int DESIRE_LEN = 8; | ||||
| constexpr int DESIRE_PRED_LEN = 4; | ||||
| constexpr int TRAFFIC_CONVENTION_LEN = 2; | ||||
| constexpr int NAV_FEATURE_LEN = 256; | ||||
| constexpr int NAV_INSTRUCTION_LEN = 150; | ||||
| constexpr int DRIVING_STYLE_LEN = 12; | ||||
| constexpr int MODEL_FREQ = 20; | ||||
| 
 | ||||
| constexpr int DISENGAGE_LEN = 5; | ||||
| constexpr int BLINKER_LEN = 6; | ||||
| constexpr int META_STRIDE = 7; | ||||
| 
 | ||||
| constexpr int PLAN_MHP_N = 5; | ||||
| constexpr int LEAD_MHP_N = 2; | ||||
| constexpr int LEAD_TRAJ_LEN = 6; | ||||
| constexpr int LEAD_MHP_SELECTION = 3; | ||||
| // Padding to get output shape as multiple of 4
 | ||||
| constexpr int PAD_SIZE = 2; | ||||
| 
 | ||||
| constexpr float FCW_THRESHOLD_5MS2_HIGH = 0.15; | ||||
| constexpr float FCW_THRESHOLD_5MS2_LOW = 0.05; | ||||
| constexpr float FCW_THRESHOLD_3MS2 = 0.7; | ||||
| 
 | ||||
| struct ModelOutputXYZ { | ||||
|   float x; | ||||
|   float y; | ||||
|   float z; | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputXYZ) == sizeof(float)*3); | ||||
| 
 | ||||
| struct ModelOutputYZ { | ||||
|   float y; | ||||
|   float z; | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputYZ) == sizeof(float)*2); | ||||
| 
 | ||||
| struct ModelOutputPlanElement { | ||||
|   ModelOutputXYZ position; | ||||
|   ModelOutputXYZ velocity; | ||||
|   ModelOutputXYZ acceleration; | ||||
|   ModelOutputXYZ rotation; | ||||
|   ModelOutputXYZ rotation_rate; | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputPlanElement) == sizeof(ModelOutputXYZ)*5); | ||||
| 
 | ||||
| struct ModelOutputPlanPrediction { | ||||
|   std::array<ModelOutputPlanElement, TRAJECTORY_SIZE> mean; | ||||
|   std::array<ModelOutputPlanElement, TRAJECTORY_SIZE> std; | ||||
|   float prob; | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputPlanPrediction) == (sizeof(ModelOutputPlanElement)*TRAJECTORY_SIZE*2) + sizeof(float)); | ||||
| 
 | ||||
| struct ModelOutputPlans { | ||||
|   std::array<ModelOutputPlanPrediction, PLAN_MHP_N> prediction; | ||||
| 
 | ||||
|   constexpr const ModelOutputPlanPrediction &get_best_prediction() const { | ||||
|     int max_idx = 0; | ||||
|     for (int i = 1; i < prediction.size(); i++) { | ||||
|       if (prediction[i].prob > prediction[max_idx].prob) { | ||||
|         max_idx = i; | ||||
|       } | ||||
|     } | ||||
|     return prediction[max_idx]; | ||||
|   } | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputPlans) == sizeof(ModelOutputPlanPrediction)*PLAN_MHP_N); | ||||
| 
 | ||||
| struct ModelOutputLinesXY { | ||||
|   std::array<ModelOutputYZ, TRAJECTORY_SIZE> left_far; | ||||
|   std::array<ModelOutputYZ, TRAJECTORY_SIZE> left_near; | ||||
|   std::array<ModelOutputYZ, TRAJECTORY_SIZE> right_near; | ||||
|   std::array<ModelOutputYZ, TRAJECTORY_SIZE> right_far; | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputLinesXY) == sizeof(ModelOutputYZ)*TRAJECTORY_SIZE*4); | ||||
| 
 | ||||
| struct ModelOutputLineProbVal { | ||||
|   float val_deprecated; | ||||
|   float val; | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputLineProbVal) == sizeof(float)*2); | ||||
| 
 | ||||
| struct ModelOutputLinesProb { | ||||
|   ModelOutputLineProbVal left_far; | ||||
|   ModelOutputLineProbVal left_near; | ||||
|   ModelOutputLineProbVal right_near; | ||||
|   ModelOutputLineProbVal right_far; | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputLinesProb) == sizeof(ModelOutputLineProbVal)*4); | ||||
| 
 | ||||
| struct ModelOutputLaneLines { | ||||
|   ModelOutputLinesXY mean; | ||||
|   ModelOutputLinesXY std; | ||||
|   ModelOutputLinesProb prob; | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputLaneLines) == (sizeof(ModelOutputLinesXY)*2) + sizeof(ModelOutputLinesProb)); | ||||
| 
 | ||||
| struct ModelOutputEdgessXY { | ||||
|   std::array<ModelOutputYZ, TRAJECTORY_SIZE> left; | ||||
|   std::array<ModelOutputYZ, TRAJECTORY_SIZE> right; | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputEdgessXY) == sizeof(ModelOutputYZ)*TRAJECTORY_SIZE*2); | ||||
| 
 | ||||
| struct ModelOutputRoadEdges { | ||||
|   ModelOutputEdgessXY mean; | ||||
|   ModelOutputEdgessXY std; | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputRoadEdges) == (sizeof(ModelOutputEdgessXY)*2)); | ||||
| 
 | ||||
| struct ModelOutputLeadElement { | ||||
|   float x; | ||||
|   float y; | ||||
|   float velocity; | ||||
|   float acceleration; | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputLeadElement) == sizeof(float)*4); | ||||
| 
 | ||||
| struct ModelOutputLeadPrediction { | ||||
|   std::array<ModelOutputLeadElement, LEAD_TRAJ_LEN> mean; | ||||
|   std::array<ModelOutputLeadElement, LEAD_TRAJ_LEN> std; | ||||
|   std::array<float, LEAD_MHP_SELECTION> prob; | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputLeadPrediction) == (sizeof(ModelOutputLeadElement)*LEAD_TRAJ_LEN*2) + (sizeof(float)*LEAD_MHP_SELECTION)); | ||||
| 
 | ||||
| struct ModelOutputLeads { | ||||
|   std::array<ModelOutputLeadPrediction, LEAD_MHP_N> prediction; | ||||
|   std::array<float, LEAD_MHP_SELECTION> prob; | ||||
| 
 | ||||
|   constexpr const ModelOutputLeadPrediction &get_best_prediction(int t_idx) const { | ||||
|     int max_idx = 0; | ||||
|     for (int i = 1; i < prediction.size(); i++) { | ||||
|       if (prediction[i].prob[t_idx] > prediction[max_idx].prob[t_idx]) { | ||||
|         max_idx = i; | ||||
|       } | ||||
|     } | ||||
|     return prediction[max_idx]; | ||||
|   } | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputLeads) == (sizeof(ModelOutputLeadPrediction)*LEAD_MHP_N) + (sizeof(float)*LEAD_MHP_SELECTION)); | ||||
| 
 | ||||
| 
 | ||||
| struct ModelOutputPose { | ||||
|   ModelOutputXYZ velocity_mean; | ||||
|   ModelOutputXYZ rotation_mean; | ||||
|   ModelOutputXYZ velocity_std; | ||||
|   ModelOutputXYZ rotation_std; | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputPose) == sizeof(ModelOutputXYZ)*4); | ||||
| 
 | ||||
| struct ModelOutputWideFromDeviceEuler { | ||||
|   ModelOutputXYZ mean; | ||||
|   ModelOutputXYZ std; | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputWideFromDeviceEuler) == sizeof(ModelOutputXYZ)*2); | ||||
| 
 | ||||
| struct ModelOutputTemporalPose { | ||||
|   ModelOutputXYZ velocity_mean; | ||||
|   ModelOutputXYZ rotation_mean; | ||||
|   ModelOutputXYZ velocity_std; | ||||
|   ModelOutputXYZ rotation_std; | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputTemporalPose) == sizeof(ModelOutputXYZ)*4); | ||||
| 
 | ||||
| struct ModelOutputRoadTransform { | ||||
|   ModelOutputXYZ position_mean; | ||||
|   ModelOutputXYZ rotation_mean; | ||||
|   ModelOutputXYZ position_std; | ||||
|   ModelOutputXYZ rotation_std; | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputRoadTransform) == sizeof(ModelOutputXYZ)*4); | ||||
| 
 | ||||
| struct ModelOutputDisengageProb { | ||||
|   float gas_disengage; | ||||
|   float brake_disengage; | ||||
|   float steer_override; | ||||
|   float brake_3ms2; | ||||
|   float brake_4ms2; | ||||
|   float brake_5ms2; | ||||
|   float gas_pressed; | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputDisengageProb) == sizeof(float)*7); | ||||
| 
 | ||||
| struct ModelOutputBlinkerProb { | ||||
|   float left; | ||||
|   float right; | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputBlinkerProb) == sizeof(float)*2); | ||||
| 
 | ||||
| struct ModelOutputDesireProb { | ||||
|   union { | ||||
|     struct { | ||||
|       float none; | ||||
|       float turn_left; | ||||
|       float turn_right; | ||||
|       float lane_change_left; | ||||
|       float lane_change_right; | ||||
|       float keep_left; | ||||
|       float keep_right; | ||||
|       float null; | ||||
|     }; | ||||
|     struct { | ||||
|       std::array<float, DESIRE_LEN> array; | ||||
|     }; | ||||
|   }; | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputDesireProb) == sizeof(float)*DESIRE_LEN); | ||||
| 
 | ||||
| struct ModelOutputMeta { | ||||
|   ModelOutputDesireProb desire_state_prob; | ||||
|   float engaged_prob; | ||||
|   std::array<ModelOutputDisengageProb, DISENGAGE_LEN> disengage_prob; | ||||
|   std::array<ModelOutputBlinkerProb, BLINKER_LEN> blinker_prob; | ||||
|   std::array<ModelOutputDesireProb, DESIRE_PRED_LEN> desire_pred_prob; | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputMeta) == sizeof(ModelOutputDesireProb) + sizeof(float) + (sizeof(ModelOutputDisengageProb)*DISENGAGE_LEN) + (sizeof(ModelOutputBlinkerProb)*BLINKER_LEN) + (sizeof(ModelOutputDesireProb)*DESIRE_PRED_LEN)); | ||||
| 
 | ||||
| struct ModelOutputFeatures { | ||||
|   std::array<float, FEATURE_LEN> feature; | ||||
| }; | ||||
| static_assert(sizeof(ModelOutputFeatures) == (sizeof(float)*FEATURE_LEN)); | ||||
| 
 | ||||
| struct ModelOutput { | ||||
|   const ModelOutputPlans plans; | ||||
|   const ModelOutputLaneLines lane_lines; | ||||
|   const ModelOutputRoadEdges road_edges; | ||||
|   const ModelOutputLeads leads; | ||||
|   const ModelOutputMeta meta; | ||||
|   const ModelOutputPose pose; | ||||
|   const ModelOutputWideFromDeviceEuler wide_from_device_euler; | ||||
|   const ModelOutputTemporalPose temporal_pose; | ||||
|   const ModelOutputRoadTransform road_transform; | ||||
| }; | ||||
| 
 | ||||
| constexpr int OUTPUT_SIZE = sizeof(ModelOutput) / sizeof(float); | ||||
| constexpr int NET_OUTPUT_SIZE = OUTPUT_SIZE + FEATURE_LEN + PAD_SIZE; | ||||
| 
 | ||||
| struct PublishState { | ||||
|   std::array<float, DISENGAGE_LEN * DISENGAGE_LEN> disengage_buffer = {}; | ||||
|   std::array<float, 5> prev_brake_5ms2_probs = {}; | ||||
|   std::array<float, 3> prev_brake_3ms2_probs = {}; | ||||
| }; | ||||
| 
 | ||||
| void fill_model_msg(MessageBuilder &msg, float *net_output_data, PublishState &ps, uint32_t vipc_frame_id, uint32_t vipc_frame_id_extra, uint32_t frame_id, float frame_drop, | ||||
|                     uint64_t timestamp_eof, uint64_t timestamp_llk, float model_execution_time, const bool nav_enabled, const bool valid); | ||||
| void fill_pose_msg(MessageBuilder &msg, float *net_outputs, uint32_t vipc_frame_id, uint32_t vipc_dropped_frames, uint64_t timestamp_eof, const bool valid); | ||||
					Loading…
					
					
				
		Reference in new issue