Example #1
0
Scales determineScaling(Function fun) {
	bool linear;
	bool sublinear;
	
	unsigned trial = 0;
	for (; trial < num_times; trial += 1) {	
		if (trial > 0 && ((times[trial - 1] * sizes[trial])	> 10)) { break; }
		setA = &setsA[trial];
		setB = &setsB[trial];
		setAPrime = &setsAPrime[trial];
		times[trial] = timeFunction(fun);
		printf("time taken for size %d was %g\n",
			sizes[trial], times[trial]);
	}
	
	if (trial < 3) {
		printf("I'm sorry, your program is way too inefficient.\n");
		printf("you'll need to find a way-faster computer to test it on\n");
		return SUPER_LINEAR;
	}
	linear = checkLinear(times, sizes, 0, trial - 1) 
		|| checkLinear(times, sizes, 1, trial - 1);
	sublinear = checkSubLinear(times, sizes, 0, trial - 1)
		|| checkSubLinear(times, sizes, 1, trial - 1);
	
	if (sublinear) { return SUB_LINEAR; }
	else if (linear) { return LINEAR; }
	else { return SUPER_LINEAR; }
}
/*
 * Step 5. Take MAX readings for 3 seconds then show results
 */
void ThrottleDetector::detectMaxCalibrate() {
	if ((millis() - startTime) < 2000 && sampleCount < maxSamples) {
		readThrottleValues();
	} else {
		displayCalibratedValues(false);

		// take some stats before normalizing min/max
		int throttle1MinFluctuation = abs(throttle1MaxRest-throttle1MinRest);
		int throttle2MinFluctuation = abs(throttle2MaxRest-throttle2MinRest);
		int throttle1MaxFluctuation = abs(throttle1Max-throttle1Min);
		int throttle2MaxFluctuation = abs(throttle2Max-throttle2Min);

		// Determine throttle type based off min/max
		if (throttle1MinRest > throttle1Min+maxThrottleReadingDeviationPercent) { // high to low pot
			throttle1HighLow = true;
		}

		if (throttle2MinRest > throttle2Min+maxThrottleReadingDeviationPercent) { // high to low pot
			throttle2HighLow = true;
		}

		// restore the true min
		throttle1Min = throttle1MinRest;

		if ((throttle1HighLow && !throttle2HighLow) || (throttle2HighLow && !throttle1HighLow)) {
			throttle2Inverse = true;
		}

		// Detect grounded pin (always zero) or floating values which indicate no potentiometer provided
		if ((throttle2MinRest == 0 && throttle2MaxRest == 0 && throttle2Min == INT16_MAX && throttle2Max == 0)
				|| (abs(throttle2MaxRest-throttle2Max) < maxThrottleReadingDeviationPercent
						&& abs(throttle2MinRest-throttle2Min) < maxThrottleReadingDeviationPercent)) {
			potentiometerCount = 1;
		} else {
			potentiometerCount = 2;
		}

		// restore the true min/max for T2
		if ( throttle2Inverse ) {
			throttle2Max = throttle2MaxRest;
		} else {
			throttle2Min = throttle2MinRest;
		}

		Logger::debug("Inverse: %s, throttle2Min: %d, throttle2Max: %d", (throttle2Inverse?"true":"false"), throttle2Min, throttle2Max);

		// fluctuation percentages - make sure not to divide by zero
		if (!(throttle1Max == throttle1Min))
		{
			throttle1MinFluctuationPercent = throttle1MinFluctuation * 100 / abs(throttle1Max - throttle1Min);
			throttle1MaxFluctuationPercent = throttle1MaxFluctuation * 100 / abs(throttle1Max - throttle1Min);
		}
		else
		{
			throttle1MinFluctuationPercent = 0;
			throttle1MaxFluctuationPercent = 0;
		}
		if (!(throttle2Max == throttle2Min))
		{
			throttle2MinFluctuationPercent = throttle2MinFluctuation * 100 / abs(throttle2Max - throttle2Min);
			throttle2MaxFluctuationPercent = throttle2MaxFluctuation * 100 / abs(throttle2Max - throttle2Min);
		}
		else
		{
			throttle2MinFluctuationPercent = 0;
			throttle2MaxFluctuationPercent = 0;
		}

		// Determine throttle subtype by examining the data sampled
		for (int i = 0; i < sampleCount; i++) {
			// normalize the values to a 0-1000 scale using the found min/max
			uint16_t value1 = normalize(throttle1Values[i], throttle1Min, throttle1Max, 0, 1000);
			uint16_t value2 = normalize(throttle2Values[i], throttle2Min, throttle2Max, 0, 1000);

			// see if they match known subtypes
			linearCount += checkLinear(value1, value2);
			inverseCount += checkInverse(value1, value2);

			//Logger::debug("T1: %d, T2: %d = NT1: %d, NT2: %d, L: %d, I: %d", throttle1Values[i], throttle2Values[i], value1, value2, linearCount, inverseCount);
		}

		throttleSubType = 0;
		if (potentiometerCount > 1) {
			// For dual pots, we trust the detection of >75%
			if ((linearCount * 100) / sampleCount > 75) {
				throttleSubType = 1;
			} else if ((inverseCount * 100) / sampleCount > 75) {
				throttleSubType = 2;
			}
		} else {
			// For single pots we use the high/low
			if (throttle1HighLow) {
				throttleSubType = 2;
			} else {
				throttleSubType = 1;
			}
		}

		char *type = "UNKNOWN";
		if (throttleSubType == 1) {
			type = "Linear";
		} else if (throttleSubType == 2) {
			type = "Inverse";
		}

		if ( Logger::isDebug()) {
			Logger::console("\n----- RAW values ----");
			for (int i = 0; i < sampleCount; i++) {
				Logger::console("T1: %d, T2: %d", throttle1Values[i], throttle2Values[i]);
			}
		}

		Logger::console("\n=======================================");
		Logger::console("Detection complete");
		Logger::console("Num samples taken: %d", sampleCount);
		Logger::console("Num potentiometers found: %d", potentiometerCount);
		Logger::console("T1: %d to %d %s", (throttle1HighLow ? throttle1Max : throttle1Min), (throttle1HighLow ? throttle1Min : throttle1Max),
				(throttle1HighLow ? "HIGH-LOW" : "LOW-HIGH"));
		Logger::console("T1: rest fluctuation %d%%, full throttle fluctuation %d%%", throttle1MinFluctuationPercent, throttle1MaxFluctuationPercent);

		if (potentiometerCount > 1) {
			Logger::console("T2: %d to %d %s %s", (throttle2HighLow ? throttle2Max : throttle2Min), (throttle2HighLow ? throttle2Min : throttle2Max),
					(throttle2HighLow ? "HIGH-LOW" : "LOW-HIGH"), (throttle2Inverse ? " (Inverse of T1)" : ""));
			Logger::console("T2: rest fluctuation %d%%, full throttle fluctuation %d%%", throttle2MinFluctuationPercent, throttle2MaxFluctuationPercent);
			Logger::console("Num linear throttle matches: %d", linearCount);
			Logger::console("Num inverse throttle matches: %d", inverseCount);
		}

		Logger::console("Throttle type: %s", type);
		Logger::console("========================================");

		// update the throttle's configuration (without storing it yet)
		config->minimumLevel1 = throttle1Min;
		config->maximumLevel1 = throttle1Max;
		config->numberPotMeters = potentiometerCount;
		if (config->numberPotMeters > 1) {
			config->minimumLevel2 = throttle2Min;
			config->maximumLevel2 = throttle2Max;
		} else {
			config->minimumLevel2 = 0;
			config->maximumLevel2 = 0;
		}
		config->throttleSubType = throttleSubType;

		// Done!
		state = DoNothing;
		TickHandler::getInstance()->detach(this);

		// send updates to ichip wifi
		DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_CONFIG_CHANGE, NULL);
	}
}