static roamdm dm_create(roam rm) { roamdm dm; /* recycle least recently used diamond from free list */ dm=rm->dm_free0; if (!dm) { /* to do: get all calling code to deal with out-of-mem failure */ /* return (roamdm)0; */ exit(1); } /* if not NEW, unlink from parents, otherwise set to not NEW */ if (dm->r_bound>=0.0f) { dm->p[0]->k[dm->i[0]]=(roamdm)0; dm_unlock(dm->p[0]); dm->p[1]->k[dm->i[1]]=(roamdm)0; dm_unlock(dm->p[1]); dm->iq=IQMAX>>1; }else dm->r_bound=0.0f;
void Mission::on_inactive() { if (_inited) { /* check if missions have changed so that feedback to ground station is given */ bool onboard_updated = false; orb_check(_navigator->get_onboard_mission_sub(), &onboard_updated); if (onboard_updated) { update_onboard_mission(); } bool offboard_updated = false; orb_check(_navigator->get_offboard_mission_sub(), &offboard_updated); if (offboard_updated) { update_offboard_mission(); } /* reset the current offboard mission if needed */ if (need_to_reset_mission(false)) { reset_offboard_mission(_offboard_mission); update_offboard_mission(); } } else { /* load missions from storage */ mission_s mission_state; dm_lock(DM_KEY_MISSION_STATE); /* read current state */ int read_res = dm_read(DM_KEY_MISSION_STATE, 0, &mission_state, sizeof(mission_s)); dm_unlock(DM_KEY_MISSION_STATE); if (read_res == sizeof(mission_s)) { _offboard_mission.dataman_id = mission_state.dataman_id; _offboard_mission.count = mission_state.count; _current_offboard_mission_index = mission_state.current_seq; } _inited = true; } check_mission_valid(); /* require takeoff after non-loiter or landing */ if (!_navigator->get_can_loiter_at_sp() || _navigator->get_land_detected()->landed) { _need_takeoff = true; /* Reset work item type to default if auto take-off has been paused or aborted, and we landed in manual mode. */ if (_work_item_type == WORK_ITEM_TYPE_TAKEOFF) { _work_item_type = WORK_ITEM_TYPE_DEFAULT; } } }
void Mission::reset_offboard_mission(struct mission_s &mission) { dm_lock(DM_KEY_MISSION_STATE); if (dm_read(DM_KEY_MISSION_STATE, 0, &mission, sizeof(mission_s)) == sizeof(mission_s)) { if (mission.dataman_id >= 0 && mission.dataman_id <= 1) { /* set current item to 0 */ mission.current_seq = 0; /* reset jump counters */ if (mission.count > 0) { dm_item_t dm_current = DM_KEY_WAYPOINTS_OFFBOARD(mission.dataman_id); for (unsigned index = 0; index < mission.count; index++) { struct mission_item_s item; const ssize_t len = sizeof(struct mission_item_s); if (dm_read(dm_current, index, &item, len) != len) { PX4_WARN("could not read mission item during reset"); break; } if (item.nav_cmd == NAV_CMD_DO_JUMP) { item.do_jump_current_count = 0; if (dm_write(dm_current, index, DM_PERSIST_POWER_ON_RESET, &item, len) != len) { PX4_WARN("could not save mission item during reset"); break; } } } } } else { mavlink_and_console_log_critical(_navigator->get_mavlink_log_pub(), "ERROR: could not read mission"); /* initialize mission state in dataman */ mission.dataman_id = 0; mission.count = 0; mission.current_seq = 0; } dm_write(DM_KEY_MISSION_STATE, 0, DM_PERSIST_POWER_ON_RESET, &mission, sizeof(mission_s)); } dm_unlock(DM_KEY_MISSION_STATE); }
void Delivery::on_inactive() { //////////////////////////////////// if (_inited) { /* check if missions have changed so that feedback to ground station is given */ bool onboard_updated = false; orb_check(_navigator->get_onboard_mission_sub(), &onboard_updated); if (onboard_updated) { update_onboard_mission(); } bool offboard_updated = false; orb_check(_navigator->get_offboard_mission_sub(), &offboard_updated); if (offboard_updated) { update_offboard_mission(); } } else { /* load missions from storage */ mission_s mission_state; dm_lock(DM_KEY_MISSION_STATE); /* read current state */ int read_res = dm_read(DM_KEY_MISSION_STATE, 0, &mission_state, sizeof(mission_s)); dm_unlock(DM_KEY_MISSION_STATE); if (read_res == sizeof(mission_s)) { _offboard_mission.dataman_id = mission_state.dataman_id; _offboard_mission.count = mission_state.count; _current_offboard_mission_index = mission_state.current_seq; } _inited = true; } check_mission_valid(); /* reset RTL state only if setpoint moved */ if (!_navigator->get_can_loiter_at_sp()) { _rtl_state = RTL_STATE_NONE; } }
void Mission::save_offboard_mission_state() { mission_s mission_state; /* lock MISSION_STATE item */ dm_lock(DM_KEY_MISSION_STATE); /* read current state */ int read_res = dm_read(DM_KEY_MISSION_STATE, 0, &mission_state, sizeof(mission_s)); if (read_res == sizeof(mission_s)) { /* data read successfully, check dataman ID and items count */ if (mission_state.dataman_id == _offboard_mission.dataman_id && mission_state.count == _offboard_mission.count) { /* navigator may modify only sequence, write modified state only if it changed */ if (mission_state.current_seq != _current_offboard_mission_index) { if (dm_write(DM_KEY_MISSION_STATE, 0, DM_PERSIST_POWER_ON_RESET, &mission_state, sizeof(mission_s)) != sizeof(mission_s)) { warnx("ERROR: can't save mission state"); mavlink_log_critical(_navigator->get_mavlink_log_pub(), "ERROR: can't save mission state"); } } } } else { /* invalid data, this must not happen and indicates error in offboard_mission publisher */ mission_state.dataman_id = _offboard_mission.dataman_id; mission_state.count = _offboard_mission.count; mission_state.current_seq = _current_offboard_mission_index; warnx("ERROR: invalid mission state"); mavlink_log_critical(_navigator->get_mavlink_log_pub(), "ERROR: invalid mission state"); /* write modified state only if changed */ if (dm_write(DM_KEY_MISSION_STATE, 0, DM_PERSIST_POWER_ON_RESET, &mission_state, sizeof(mission_s)) != sizeof(mission_s)) { warnx("ERROR: can't save mission state"); mavlink_log_critical(_navigator->get_mavlink_log_pub(), "ERROR: can't save mission state"); } } /* unlock MISSION_STATE item */ dm_unlock(DM_KEY_MISSION_STATE); }
void Mission::on_inactive() { if (_inited) { /* check if missions have changed so that feedback to ground station is given */ bool onboard_updated = false; orb_check(_navigator->get_onboard_mission_sub(), &onboard_updated); if (onboard_updated) { update_onboard_mission(); } bool offboard_updated = false; orb_check(_navigator->get_offboard_mission_sub(), &offboard_updated); if (offboard_updated) { update_offboard_mission(); } } else { /* load missions from storage */ mission_s mission_state; dm_lock(DM_KEY_MISSION_STATE); /* read current state */ int read_res = dm_read(DM_KEY_MISSION_STATE, 0, &mission_state, sizeof(mission_s)); dm_unlock(DM_KEY_MISSION_STATE); if (read_res == sizeof(mission_s)) { _offboard_mission.dataman_id = mission_state.dataman_id; _offboard_mission.count = mission_state.count; _current_offboard_mission_index = mission_state.current_seq; } _inited = true; } check_mission_valid(); /* require takeoff after non-loiter or landing */ if (!_navigator->get_can_loiter_at_sp() || _navigator->get_vstatus()->condition_landed) { _need_takeoff = true; } }
static void dm_split(roamdm dm) { int i,s; roamdm k,p; /* if already split, then skip */ if (dm->flags&ROAM_SPLIT) return; /* split parents as needed recursively */ for (i=0;i<2;i++) { p=dm->p[i]; dm_split(p); /* if dm is p's first split kid, take p off of mergeq */ if (!(p->splitflags&SPLIT_K)) dm_enqueue(p,ROAM_UNQ,p->iq); p->splitflags|=SPLIT_K0<<dm->i[i]; } /* fetch kids, update cull/priority, and put on split queue */ for (i=0;i<4;i++) { k=dm_fetchkid(dm,i); dm_cull_update(k); dm_priority_update(k); /* kids of a freshly-split diamond go on splitq */ dm_enqueue(k,ROAM_SPLITQ,k->iq); s=(k->p[1]==dm?1:0); k->splitflags|=SPLIT_P0<<s; dm_unlock(k); dm_grabtri(k,s); /* put kid tris on draw list */ } /* indicate diamond is split, update queueing, add to check list */ dm->flags|=ROAM_SPLIT; dm_enqueue(dm,ROAM_MERGEQ,dm->iq); /* freshly-split dm goes on mergeq */ /* put any triangles back on free list */ dm_freetri(dm,0); dm_freetri(dm,1); }
void Mission::on_inactive() { /* We need to reset the mission cruising speed, otherwise the * mission velocity which might have been set using mission items * is used for missions such as RTL. */ _navigator->set_cruising_speed(); /* Without home a mission can't be valid yet anyway, let's wait. */ if (!_navigator->home_position_valid()) { return; } if (_inited) { /* check if missions have changed so that feedback to ground station is given */ bool onboard_updated = false; orb_check(_navigator->get_onboard_mission_sub(), &onboard_updated); if (onboard_updated) { update_onboard_mission(); } bool offboard_updated = false; orb_check(_navigator->get_offboard_mission_sub(), &offboard_updated); if (offboard_updated) { update_offboard_mission(); } /* reset the current offboard mission if needed */ if (need_to_reset_mission(false)) { reset_offboard_mission(_offboard_mission); update_offboard_mission(); } } else { /* load missions from storage */ mission_s mission_state; dm_lock(DM_KEY_MISSION_STATE); /* read current state */ int read_res = dm_read(DM_KEY_MISSION_STATE, 0, &mission_state, sizeof(mission_s)); dm_unlock(DM_KEY_MISSION_STATE); if (read_res == sizeof(mission_s)) { _offboard_mission.dataman_id = mission_state.dataman_id; _offboard_mission.count = mission_state.count; _current_offboard_mission_index = mission_state.current_seq; } /* On init let's check the mission, maybe there is already one available. */ check_mission_valid(false); _inited = true; } /* require takeoff after non-loiter or landing */ if (!_navigator->get_can_loiter_at_sp() || _navigator->get_land_detected()->landed) { _need_takeoff = true; /* Reset work item type to default if auto take-off has been paused or aborted, and we landed in manual mode. */ if (_work_item_type == WORK_ITEM_TYPE_TAKEOFF) { _work_item_type = WORK_ITEM_TYPE_DEFAULT; } } }