string SimpleDriver::drive(string sensors) {
    CarState cs(sensors);
    CarControl nextVector = CarControl(0.0f, 0.0f, cs.getGear(), 0.0f, 0.0f);

    if (automatedControl == NULL) {
        Keyboard_Update(&nextVector);
        log->push_back(pair<CarState, CarControl>(cs, nextVector));
    } else {
        this->automatedControl->generateVector(&cs, &nextVector);
    }

    return nextVector.toString();
}
Exemple #2
0
string 
TTIWrapperDriver::drive(string sensors)
{
	CarState cs(sensors);
	current=cs;
	curTick++;
	if(zombie){
		CarControl cc;
		cc.setMeta(2);
		return cc.toString();
	} 
	if(isDead()){
		clear();
		zombie=true;
		std::cout<<"terminated"<<std::endl;
		CarControl cc;
		cc.setMeta(2);
		return cc.toString();
	}
	float lap = current.getLastLapTime();
	if(lap!=lastLap){
		lapTimes.push_back(lap);
		lastLap=lap;
	}
	if(current.getTrackPos()>=1||current.getTrackPos()<=-1){
		outside++;
	}
	CarControl cc = wDrive(cs);
	return cc.toString();	
}
CarControl MyDriver::wDrive(CarState cs){
	// Update clock variables for graphing over time
	_timePrevious = _timeCurrent;
	_timeCurrent = Clock::now();

	_dt = _timeCurrent - _timePrevious;
	_runtime += _dt;

	if (_logging)
		Renderer::get().setWindowTitle(std::to_string(_dt.count()));


	// Temporarily copy old sensors to delta and reset sensors with max distance
	memcpy(&_driving.delta[0], &_driving.sensors[0], sizeof(_driving.sensors));
	std::fill_n(_driving.sensors, ALL_SENSORS, 200.f);
	

	// Directly mapping track sensors to front 19 sensors
	int zero = 0;

	for (int i = 0; i < HALF_SENSORS; i++){
		float distance = cs.getTrack(i);

		if (distance <= 0.f)
			zero++;

		if (distance < _driving.sensors[i + QUART_SENSORS])
			_driving.sensors[i + QUART_SENSORS] = distance;
	}

	if (zero == 19)
		_driving.crashed = true;
	else if (_driving.crashed)
		_driving.crashed = false;
	

	// Iterate through opponent sensors
	for (int i = 0; i < ALL_SENSORS; i++){
		//std::cout << "i - " << i << "\n";

		float distance = cs.getOpponents(i);

		// If no opponent, skip sensor
		if (distance >= _awarnessOpponent * 200.f)
			continue;

		// Calculate amount of track sensors to block, and round to nearest even integer
		float raw = distance / (_awarnessOpponent * 200.f);

		float block = ((1.f - raw) * (float)((_maxBlock - 2) + 2));
		
		block = glm::roundEven(block);

		// Apply smaller distances to sensor array
		for (int x = block / 2; x >= -(block / 2 - 1); x--){
			int sensor = (i + x) % ALL_SENSORS;
		
			float dropOff = glm::abs(changeRange(block / 2, -(block / 2 - 1), -1.f, 1.f, x));

			if (_driving.sensors[sensor] > distance + dropOff * _blockDropOff)
				_driving.sensors[sensor] = distance + dropOff * _blockDropOff;
		}
	}
	

	// Calculate difference using old sensors stored in delta
	for (int i = 0; i < ALL_SENSORS; i++){
		_driving.delta[i] = _driving.delta[i] - _driving.sensors[i];

		if (_driving.delta[i] < 0.f)
			_driving.delta[i] = glm::abs(_driving.delta[i]);
		else
			_driving.delta[i] = 0.f;

		if (_driving.delta[i] > 0.25f)
			_driving.delta[i] = 0.f;
	}


	// Decreasing sensors around furthest ray 
	//		if furthest ray is on left, decrease right sensors 
	//		if furthest ray is on right, decrease left sensors
	//		if furthest ray is in the middle, decrease both sides sensors
	if (_driving.furthestRay <= QUART_SENSORS){
		for (int i = _driving.furthestRay; i < HALF_SENSORS; i++){
			_driving.sensors[QUART_SENSORS + i] *= changeRange(_driving.furthestRay, 18, 1, 0, i);
		}
	}
	
	if (_driving.furthestRay >= QUART_SENSORS){
		for (int i = _driving.furthestRay; i >= 0; i--){
			_driving.sensors[QUART_SENSORS + i] *= changeRange(_driving.furthestRay, 0, 1, 0, i);
		}
	}

	
	// Choosing which ray to steer towards, and how fast
	float maxDistance = _driving.sensors[_driving.furthestRay + QUART_SENSORS];

	for (int i = 0; i < HALF_SENSORS; i++){
		float distance = _driving.sensors[i + QUART_SENSORS];

		if (maxDistance < distance){
			maxDistance = distance;
			_driving.furthestRay = i;
		}
	}


	// P - PID
	float proportional = (changeRange(0.f, 18.f, 1.5f, -1.5f, _driving.furthestRay) - (cs.getTrackPos() / 500.f)) - cs.getTrackPos() * _middleDrift;

	proportional *= _p;


	// I - PID
	while (_driving.steerHistory.size() > _historySteerLength)
		_driving.steerHistory.erase(_driving.steerHistory.begin());

	float integral = 0.f;

	for (float i : _driving.steerHistory)
		integral += i;

	integral *= _i;


	// D - PID
	float derivative = 0.f;

	if (_driving.steerHistory.size() >= 2)
		derivative = _driving.steerHistory[_driving.steerHistory.size() - 1] - _driving.steerHistory[_driving.steerHistory.size() - 2];

	derivative *= _d;


	// P + I + D
	float oldSteer = _driving.steer;

	_driving.steer = proportional + integral + derivative;

	_driving.steerHistory.push_back(_driving.steer);

	_driving.steer = glm::mix(oldSteer, _driving.steer, _easeSteer);


	// Speed control
	if (!_driving.crashed){
		float speed = _driving.sensors[_driving.furthestRay + QUART_SENSORS] / (200.f * _awarnessTrack) + _driving.delta[_driving.furthestRay + QUART_SENSORS] * 8.f;

		speed *= (1.f - _speedRestrict);

		_driving.speed = glm::mix(_driving.speed, speed, _easeAccel); //*(1.f - cs.getTrack(QUART_SENSORS)) * brake;

		float brake = (cs.getSpeedX() / 200.f) - _driving.speed;

		if (brake > 0.f)
			_driving.brake = glm::mix(_driving.brake, brake, _easeBrake);
		else
			_driving.brake = 0.f;
	}


	// Changing gears
	int gear = cs.getGear();
	int rpm = cs.getRpm();

	if (gear < 1)
		_driving.gear = 1;

	if (gear < 6 && rpm >= _gearUp[gear - 1])
		_driving.gear = gear + 1;
	else
		if (gear > 1 && rpm <= _gearDown[gear - 1])
			_driving.gear = gear - 1;
	

	// If logging, render sensors
	if (_logging){
		Renderer::get().drawGraph({ _runtime.count() / 100.f, _driving.steer }, 0);
		Renderer::get().drawGraph({ _runtime.count() / 100.f, _driving.speed }, 1);
		Renderer::get().drawGraph({ _runtime.count() / 100.f, _driving.brake }, 2);

		for (int i = 0; i < ALL_SENSORS; i++){
			float distance = _driving.sensors[i];

			if (distance < 0.1f)
				continue;
		
			float radians = glm::radians(i * 10.f);
		
			glm::vec2 point = { -glm::sin(radians), -glm::cos(radians) };
		
			glm::vec3 colour = { 1.f, 1.f, 1.f };
		
			if (_driving.furthestRay + QUART_SENSORS == i)
				colour = { 0.f, 1.f, 0.f };

			float zoom = 10.f;

			Renderer::get().drawLine({ 0, 0 }, point * distance * zoom, colour);
		}

		if (_driving.crashed)
			std::cout << "Crashed!\n";

		// Un-comment for pointless cool effects
		Renderer::get().setRotation(cs.getAngle() * 90.f);
		Renderer::get().setZoom(1.f + cs.getSpeedX() / 200.f);
	}


	// Applying to controller
	CarControl cc;

	cc.setGear(_driving.gear);
	cc.setAccel(_driving.speed);
	cc.setSteer(_driving.steer);
	cc.setBrake(_driving.brake);

	return cc;
}