Example #1
0
int sbSetNavAndWait(struct SBControlContext *control, 
		int setmode, int waitmode,double timout_sec)
{
	SBHeliState state;
	int res;
	double t,t0 = now();
	sbLockCommunication(control);
	DEBUG(res = sbSetNavMode(control,setmode));
	sbUnlockCommunication(control);
	if (res) return res;
	while (1) {
		sbLockCommunication(control);
		DEBUG(res = sbRequestState(control, SBS_MODES, &state));
		sbUnlockCommunication(control);
		if (res) return res;

		if (state.mode.navigation == waitmode){
			break;
		}
		t = now(); 
		if (t < t0) t += 86400; // time of day wrap around
		if ((t - t0) > timout_sec) {
			break;
		}
#ifdef LINUX
		usleep(5000);
#endif
#ifdef WIN32
		Sleep(5);
#endif
	}
	return (state.mode.navigation == waitmode)?0:+1;
}
Example #2
0
int sbSimpleReachNavState(SBApiSimpleContext *context, 
		int desired, double timeout_sec)
{
	int res;
	SBHeliState state;
	double t0 = now();
	double t_lastprint = -2;

	static int transition[8*8] = {
	// to:  stop         idle	      takeoff         land         hover           cntrl           sink  raw     
			SB_NAV_STOP, SB_NAV_IDLE, SB_NAV_IDLE,             -1, SB_NAV_IDLE,    SB_NAV_IDLE,    -1,   SB_NAV_RAW,// from stop
			SB_NAV_STOP, SB_NAV_IDLE, SB_NAV_TAKEOFF,          -1, SB_NAV_TAKEOFF, SB_NAV_TAKEOFF, -1,   SB_NAV_STOP, // from idle
			SB_NAV_LAND, SB_NAV_LAND, SB_NAV_TAKEOFF, SB_NAV_LAND, SB_NAV_TAKEOFF, SB_NAV_TAKEOFF, -1,   SB_NAV_LAND,// from takeoff
			SB_NAV_LAND, SB_NAV_LAND, SB_NAV_LAND,    SB_NAV_LAND, SB_NAV_LAND,    SB_NAV_LAND,    -1,   SB_NAV_LAND,// from land
			SB_NAV_LAND, SB_NAV_LAND, SB_NAV_LAND,    SB_NAV_LAND, SB_NAV_HOVER,   SB_NAV_CTRLLED, -1,   SB_NAV_LAND,// from hover
			SB_NAV_LAND, SB_NAV_LAND, SB_NAV_LAND,    SB_NAV_LAND, SB_NAV_HOVER,   SB_NAV_CTRLLED, -1,   SB_NAV_LAND,// from ctrlled
			SB_NAV_LAND, SB_NAV_LAND, SB_NAV_LAND,    SB_NAV_LAND, SB_NAV_HOVER,   SB_NAV_CTRLLED, -1,   SB_NAV_LAND,// from sink
			SB_NAV_STOP, SB_NAV_STOP,          -1,    SB_NAV_LAND, SB_NAV_LAND,    SB_NAV_LAND,    -1,   SB_NAV_RAW  // from raw (no transition allowed)
	};

	switch (desired) {
		case SB_NAV_TAKEOFF:
		case SB_NAV_LAND:
			printf("sbSimpleReachNavState: Take-off and landing mode are transcient and cannot be used as target for sbSimpleReachNavState\n");
			return -1;
		case SB_NAV_SINK:
			printf("sbSimpleReachNavState: Sink mode is an error mode and cannot be used as target for sbSimpleReachNavState\n");
			return -1;
		default:
			break;
	}

	switch (context->commMode) {
		case SB_COM_CONTINUOUS:
			DEBUG(res = sbSimpleWaitState(context,&state,1.0));
			break;
		case SB_COM_ONREQUEST:
			sbLockCommunication(&context->control);
			DEBUG(res = sbRequestState(&context->control,SBS_MODES,&state));
			sbUnlockCommunication(&context->control);
			break;
		default:
			res = -1;
	}

	if (res) {
		printf("sbSimpleReachNavState: Could not receive initial state\n");
		return -1;
	}
	if (!(state.content & SBS_MODES)) {
		printf("sbSimpleReachNavState: initial state did not contains MODES\n");
		return -1;
	}
	if (desired == state.mode.navigation) {
		return 0;
	}

    if ((desired != SB_NAV_STOP) && (state.errorFlags)) {
		printf("sbSimpleReachNavState: refusing to switch mode while error flags are raised\n");
        sbErrorPrint(stdout,state.errorFlags);
        return -1;
    }

	while (state.mode.navigation != desired) {
		double t = now();
		int nextstate;
		switch (context->commMode) {
			case SB_COM_CONTINUOUS:
				DEBUG(res = sbSimpleWaitState(context,&state,1.0));
				break;
			case SB_COM_ONREQUEST:
				sbLockCommunication(&context->control);
				DEBUG(res = sbRequestState(&context->control,SBS_MODES,&state));
				sbUnlockCommunication(&context->control);
				break;
			default:
				res = -1;
		}
		if (res) {
			printf("sbSimpleReachNavState: failed to receive state\n");
			return -4;
		}
		nextstate = transition[state.mode.navigation*8+desired];
		// Testing the validity of the transition
		if (nextstate < 0) {
			printf("sbSimpleReachNavState: cannot reach desired state. Aborting\n");
			return -2;
		}
		// printf("sbSimpleReachNavState: next state = %d / current %d\n",nextstate, state.mode.navigation);
		if (t < t0) t += 86400;
		if (t > t0 + timeout_sec) {
			printf("sbSimpleReachNavState timed out. Aborting\n");
			return -2;
		}

		if (t - t_lastprint > 2) {
			printf("Current %s desired: %s next %s wait %s rem t %.3f\n",
					sbNavModeString(state.mode.navigation),
					sbNavModeString(desired),sbNavModeString(nextstate),
					sbNavModeString(waitmode(nextstate)),t0 + timeout_sec - t);
			t_lastprint = t;
		}

		// Requesting the transition
		sbLockCommunication(&context->control);
		res = sbSetNavMode(&context->control,nextstate);
		res = sbKeepAlive(&context->control);
		sbUnlockCommunication(&context->control);
		switch (res) {
			case 0:
				// Good, it works
				break;
			case SB_REPLY_TOO_EARLY:
				continue;
				break;
			default:
				printf("sbSetNavAndWait failed (%d) to set desired mode. Aborting\n",res);
		}

#ifdef LINUX
		usleep(100000);
#endif
#ifdef WIN32
		Sleep(100);
#endif
	}
	// At this stage, the mode is the desired mode.
	if (state.mode.navigation == SB_NAV_CTRLLED) {
		// Confirm the control mode when we reach the
		// controlled state
		sbLockCommunication(&context->control);
		res = sbConfigureControl(&context->control,
				context->rollCtrlMode, context->pitchCtrlMode, 
				context->yawCtrlMode, context->altCtrlMode);
		sbUnlockCommunication(&context->control);
	}

	return 0;
}