diff --git a/combines.lua b/combines.lua
index 0d77ba7f6..b9ae3ceb8 100644
--- a/combines.lua
+++ b/combines.lua
@@ -325,7 +325,9 @@ function courseplay:calculateInitialCombineOffset(self, combine)
 	end;
 
 	--special tools, special cases
-	if combine.cp.isJohnDeereS650 then
+	if combine.cp.isJohnDeereS690i then
+		self.cp.combineOffset =  9.5;
+	elseif combine.cp.isJohnDeereS650 then
 		self.cp.combineOffset =  7.7;
 	elseif combine.cp.isCaseIH7130 then
 		self.cp.combineOffset =  8.0;
diff --git a/drive.lua b/drive.lua
index 1b66f1c3b..261143f03 100644
--- a/drive.lua
+++ b/drive.lua
@@ -156,15 +156,10 @@ function courseplay:drive(self, dt)
 		courseplay:unregister_at_combine(self, self.cp.activeCombine)
 	end
 
-	-- switch lights on!
+	-- Turn on sound / control lights
 	if not self.isControlled then
-		-- we want to hear our courseplayers
-		setVisibility(self.aiMotorSound, true)
-		if courseplay.lightsNeeded then
-			self:setLightsVisibility(true);
-		else
-			self:setLightsVisibility(false);
-		end;
+		setVisibility(self.aiMotorSound, true); --TODO (Jakob): still needed in FS13?
+		self:setLightsVisibility(courseplay.lightsNeeded);
 	end;
 
 	-- current position
@@ -668,6 +663,7 @@ function courseplay:drive(self, dt)
 		allowedToDrive = courseplay:brakeToStop(self)
 	end 
 
+	-- MODE 9 --TODO (Jakob): why is this in drive instead of mode9?
 	local WpUnload = false
 	if self.cp.shovelEmptyPoint ~= nil and self.recordnumber >=3  then
 		WpUnload = self.recordnumber == self.cp.shovelEmptyPoint
@@ -700,6 +696,7 @@ function courseplay:drive(self, dt)
 			end
 		end
 	end
+	-- MODE 9 END
 
 
 
@@ -829,8 +826,8 @@ function courseplay:drive(self, dt)
 	else
 		courseplay:setSpeed(self, refSpeed, self.cp.speeds.sl)
 	end
-	
-	-- go, go, go!
+
+	-- DISTANCE TO CHANGE WAYPOINT
 	if self.recordnumber == 1 or self.recordnumber == self.maxnumber - 1 or self.Waypoints[self.recordnumber].turn then
 		if self.cp.hasSpecializationArticulatedAxis then
 			distToChange = self.cp.mode == 9 and 2 or 1; -- ArticulatedAxis vehicles
@@ -1063,96 +1060,86 @@ function courseplay:deleteCollisionVehicle(vehicle)
 	end
 end
 
-function courseplay:setSpeed(self, refSpeed, sl)
-	if self.lastSpeedSave ~= self.lastSpeedReal*3600 then		
-		if refSpeed*3600 == 1 then
-			refSpeed = 1.6 / 3600
+function courseplay:setSpeed(vehicle, refSpeed, sl)
+	if vehicle.lastSpeedSave ~= vehicle.lastSpeedReal*3600 then
+		local refSpeedKph = refSpeed * 3600;
+		local lastSpeedKph = vehicle.lastSpeed * 3600;
+
+		if refSpeedKph == 1 then
+			refSpeed = 1.6 / 3600;
+			refSpeedKph = 1.6;
 		end
-		local trueRpm = self.motor.lastMotorRpm*100/self.cp.orgRpm[3]
-		local targetRpm = self.motor.maxRpm[sl]*100/self.cp.orgRpm[3]	
-		local newLimit = 0
-		local oldLimit = 0 
-		if self.ESLimiter ~= nil then 
-			oldLimit =  self.ESLimiter.percentage[sl+1]
+		local trueRpm = vehicle.motor.lastMotorRpm*100/vehicle.cp.orgRpm[3];
+		local targetRpm = vehicle.motor.maxRpm[sl]*100/vehicle.cp.orgRpm[3];
+		local newLimit = 0;
+		local oldLimit = 0 ;
+		if vehicle.ESLimiter ~= nil then 
+			oldLimit =  vehicle.ESLimiter.percentage[sl+1];
 		else
-			oldLimit = targetRpm
-		end
+			oldLimit = targetRpm;
+		end;
 
-		if refSpeed*3600 - self.lastSpeed*3600 > 15 then
+		local speedDelta = refSpeedKph - lastSpeedKph; -- accelerate
+		if speedDelta > 15 then
 			if sl == 2 then
-				newLimit = 75
+				newLimit = 75;
 			else
-				newLimit = 100
-			end
-		elseif refSpeed*3600 - self.lastSpeed*3600 > 4 then
-			newLimit = oldLimit + 1
-		elseif refSpeed*3600 - self.lastSpeed*3600 > 0.5 then
-			newLimit = oldLimit + 0.1
-		elseif refSpeed*3600 - self.lastSpeed*3600 > 0 then	
-			newLimit = oldLimit
-		end
+				newLimit = 100;
+			end;
+		elseif speedDelta > 4 then
+			newLimit = oldLimit + 1;
+		elseif speedDelta > 0.5 then
+			newLimit = oldLimit + 0.1;
+		elseif speedDelta > 0 then
+			newLimit = oldLimit;
+		end;
 		if oldLimit - trueRpm > 10 then
-			if refSpeed*3600 - self.lastSpeed*3600 < 1 then
-				newLimit = trueRpm
-			
-			end
-		end
-		if self.lastSpeed*3600 - refSpeed*3600 > 8 and self.cp.isTurning == nil then
+			if speedDelta < 1 then
+				newLimit = trueRpm;
+			end;
+		end;
+
+		speedDelta = lastSpeedKph - refSpeedKph; --decelerate
+		if speedDelta > 8 and vehicle.cp.isTurning == nil then
 			if sl == 1 then
-				newLimit = 20
-			else			
-				newLimit = oldLimit - 3
-			end
-		elseif self.lastSpeed*3600 - refSpeed*3600 > 3 then
-			newLimit = oldLimit -1
-		elseif self.lastSpeed*3600 - refSpeed*3600 > 1 then
-			newLimit = oldLimit -0.75
-		elseif self.lastSpeed*3600 - refSpeed*3600 > 0.5 then
-			newLimit = oldLimit -0.25
-		elseif self.lastSpeed*3600 - refSpeed*3600 > 0 then
-			newLimit = oldLimit
-		end
-		
-		if newLimit > 100 then
-			newLimit = 100
-		elseif newLimit < 0 then
-			newLimit = 0
-		end
+				newLimit = 20;
+			else
+				newLimit = oldLimit - 3;
+			end;
+		elseif speedDelta > 3 then
+			newLimit = oldLimit - 1;
+		elseif speedDelta > 1 then
+			newLimit = oldLimit - 0.75;
+		elseif speedDelta > 0.5 then
+			newLimit = oldLimit - 0.25;
+		elseif speedDelta > 0 then
+			newLimit = oldLimit;
+		end;
 
-		if self.ESLimiter ~= nil and self.ESLimiter.maxRPM[5] ~= nil then
-			self:setNewLimit(sl+1, newLimit , false, true)
-		elseif self.ESLimiter ~= nil and self.ESLimiter.maxRPM[5] == nil then
+		newLimit = Utils.clamp(newLimit, 0, 100);
+
+		if vehicle.ESLimiter ~= nil and vehicle.ESLimiter.maxRPM[5] ~= nil then
+			vehicle:setNewLimit(sl + 1, newLimit, false, true);
+		elseif vehicle.ESLimiter ~= nil and vehicle.ESLimiter.maxRPM[5] == nil then
 			--ESlimiter < V3
 		else
-			local maxRpm = newLimit * self.cp.orgRpm[3]/100
-			
-			-- don't drive faster/slower than you can!
-			if maxRpm > self.cp.orgRpm[3] then
-				maxRpm = self.cp.orgRpm[3]
-			elseif maxRpm < self.motor.minRpm then
-				maxRpm = self.motor.minRpm
-			end
-			self.motor.maxRpm[sl]= maxRpm
-		end
+			vehicle.motor.maxRpm[sl] = Utils.clamp(newLimit * vehicle.cp.orgRpm[3]/100, vehicle.motor.minRpm, vehicle.cp.orgRpm[3]);
+		end;
 
-		self.lastSpeedSave = self.lastSpeedReal*3600
-	end
+		vehicle.lastSpeedSave = vehicle.lastSpeedReal*3600;
+	end;
 
 	-- slipping notification
-	-- print(string.format('%s: lastSpeedSave=%.1f', nameNum(self), self.lastSpeedSave));
-	if self.lastSpeedSave < 0.5 and not self.cp.inTraffic and not self.Waypoints[self.recordnumber].wait then
-		if self.cp.timers.slippingWheels == nil or self.cp.timers.slippingWheels == 0 then
-			courseplay:setCustomTimer(self, 'slippingWheels', 5);
-			-- print(string.format('\tsetCustomTimer(..., "slippingWheels", 5)'));
-		elseif courseplay:timerIsThrough(self, 'slippingWheels') then
-			courseplay:setGlobalInfoText(self, 'SLIPPING_0');
-			-- print(string.format('\ttimerIsThrough -> SLIPPING'));
+	if vehicle.lastSpeedSave < 0.5 and not vehicle.cp.inTraffic and not vehicle.Waypoints[vehicle.recordnumber].wait then
+		if vehicle.cp.timers.slippingWheels == nil or vehicle.cp.timers.slippingWheels == 0 then
+			courseplay:setCustomTimer(vehicle, 'slippingWheels', 5);
+		elseif courseplay:timerIsThrough(vehicle, 'slippingWheels') then
+			courseplay:setGlobalInfoText(vehicle, 'SLIPPING_0');
 		end;
 
 	-- reset timer
-	elseif self.cp.timers.slippingWheels ~= 0 then
-		self.cp.timers.slippingWheels = 0;
-		-- print(string.format('\treset timer'));
+	elseif vehicle.cp.timers.slippingWheels ~= 0 then
+		vehicle.cp.timers.slippingWheels = 0;
 	end;
 end;
 
diff --git a/modDesc.xml b/modDesc.xml
index 30eaaa669..483777923 100644
--- a/modDesc.xml
+++ b/modDesc.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="no" ?>
 <modDesc descVersion="13">
-	<version>3.41.0455</version>
+	<version>3.41.0456</version>
 	<author><![CDATA[Jakob Tischler, Thomas Gärtner,
 Horoman, Satis]]></author>
 	<title>
diff --git a/mode1.lua b/mode1.lua
index 3a79b04db..cf332f3a5 100644
--- a/mode1.lua
+++ b/mode1.lua
@@ -42,7 +42,7 @@ function courseplay:handle_mode1(self)
 			local ctx, cty, ctz = getWorldTranslation(self.rootNode);
 			local distance_to_trigger = courseplay:distance(ctx, ctz, trigger_x, trigger_z);
 
-			-- Star reversion value is to check if we have started to reverse
+			-- Start reversion value is to check if we have started to reverse
 			-- This is used in case we already registered a tipTrigger but changed the direction and might not be in that tipTrigger when unloading. (Bug Fix)
 			local startReversing = self.Waypoints[self.recordnumber].rev and not self.Waypoints[self.cp.last_recordnumber].rev and not self.cp.BGASelectedSection;
 			if startReversing then
diff --git a/mode2.lua b/mode2.lua
index cf7af9b3c..8c07c24fe 100644
--- a/mode2.lua
+++ b/mode2.lua
@@ -716,7 +716,7 @@ function courseplay:unload_combine(self, dt)
 			if combine.cp.isChopper then
 				local fruitSide = courseplay:sideToDrive(self, combine, -10,true);
 				
-				--new chopper turn maneuver by Thomas G�rtner  
+				--new chopper turn maneuver by Thomas Gärtner  
 				if fruitSide == "left" then -- chopper will turn left
 
 					if self.cp.combineOffset > 0 then -- I'm left of chopper
@@ -1324,7 +1324,9 @@ function courseplay:calculateCombineOffset(self, combine)
 	end;
 
 	--special tools, special cases
-	if self.cp.combineOffsetAutoMode and combine.cp.isJohnDeereS650 then
+	if self.cp.combineOffsetAutoMode and combine.cp.isJohnDeereS690i then
+		offs =  9.5;
+	elseif self.cp.combineOffsetAutoMode and combine.cp.isJohnDeereS650 then
 		offs =  7.7;
 	elseif self.cp.combineOffsetAutoMode and combine.cp.isCaseIH7130 then
 		offs =  8.0;
diff --git a/specialTools.lua b/specialTools.lua
index 3b25b3138..6a980d3b4 100644
--- a/specialTools.lua
+++ b/specialTools.lua
@@ -56,8 +56,12 @@ function courseplay:setNameVariable(workTool)
 	--------------------------------------------------------------
 
 
+	--John Deere S690i [Big Boss Modding]
+	if Utils.endsWith(workTool.configFileName, 'JohnDeereS690i.xml') or Utils.endsWith(workTool.configFileName, 'JohnDeereS690i_TT.xml') then
+		workTool.cp.isJohnDeereS690i = true;
+
 	--John Deere S650 [Big Boss Modding]
-	if Utils.endsWith(workTool.configFileName, 'JohnDeereS650NW.xml') then
+	elseif Utils.endsWith(workTool.configFileName, 'JohnDeereS650NW.xml') then
 		workTool.cp.isJohnDeereS650 = true;
 
 	-- Claas Quantum 3800K [Vertex Design]
@@ -1171,7 +1175,11 @@ end
 function courseplay:askForSpecialSettings(self,object)
 	local automaticToolOffsetX;
 
-	if self.cp.isWeidemann4270CX100T  then
+	if self.cp.isJohnDeereS690i and not self.isRealistic then
+		if self.motor.maxTorques[1] > 0 then
+			self.motor.maxTorques[1] = -self.motor.maxTorques[1];
+		end;
+	elseif self.cp.isWeidemann4270CX100T  then
 		local frontPart_vis = getParent(self.movingTools[1].node)
 		local frontPart = getParent(frontPart_vis)
 		self.aiTrafficCollisionTrigger = getChild(frontPart, "trafficCollisionTrigger");
diff --git a/turn.lua b/turn.lua
index 589a835d7..d3129d0ae 100644
--- a/turn.lua
+++ b/turn.lua
@@ -1,4 +1,14 @@
 function courseplay:turn(self, dt) --!!!
+	--[[ TURN STAGES:
+	0:	raise implements
+	1:	start forward turn
+	2:	
+	3:	reversing
+	4:	
+	5:	
+	6:	
+	]]
+
 	local newTargetX, newTargetY, newTargetZ;
 	local moveForwards = true;
 	local updateWheels = true;
@@ -10,7 +20,12 @@ function courseplay:turn(self, dt) --!!!
 		turnOutTimer = 0
 	end
 	self.cp.turnTimer = self.cp.turnTimer - dt;
+
+
+	-- TURN STAGES 1 - 6
 	if self.cp.turnTimer < 0 or self.cp.turnStage > 0 then
+
+		-- TURN STAGES 2 - 6
 		if self.cp.turnStage > 1 then
 			local x,y,z = getWorldTranslation(self.rootNode);
 			local dirX, dirZ = self.aiTractorDirectionX, self.aiTractorDirectionZ;
@@ -19,6 +34,8 @@ function courseplay:turn(self, dt) --!!!
 			newTargetX = self.aiTractorTargetX;
 			newTargetY = y;
 			newTargetZ = self.aiTractorTargetZ;
+
+			-- TURN STAGE 2
 			if self.cp.turnStage == 2 then
 				self.turnStageTimer = self.turnStageTimer - dt;
 				if self.cp.isTurning == "left" then
@@ -46,6 +63,8 @@ function courseplay:turn(self, dt) --!!!
 						self.turnStageTimer = Utils.getNoNil(self.turnStage3Timeout,20000)
 					end;
 				end;
+
+			-- TURN STAGE 3
 			elseif self.cp.turnStage == 3 then
 				self.turnStageTimer = self.turnStageTimer - dt;
 				if myDirX*dirX + myDirZ*dirZ > 0.95 or self.turnStageTimer < 0 then
@@ -53,6 +72,8 @@ function courseplay:turn(self, dt) --!!!
 				else
 					moveForwards = false;
 				end;
+
+			-- TURN STAGE 4
 			elseif self.cp.turnStage == 4 then
 				local dx, dz = x-newTargetX, z-newTargetZ;
 				local dot = dx*dirX + dz*dirZ;
@@ -71,6 +92,8 @@ function courseplay:turn(self, dt) --!!!
 					end
 					self.cp.turnStage = 5;
 				end;
+
+			-- TURN STAGE 5
 			elseif self.cp.turnStage == 5 then
 				local backX, backY, backZ = localToWorld(self.rootNode,0,0,frontMarker);
 				local dx, dz = backX-newTargetX, backZ-newTargetZ;
@@ -109,6 +132,7 @@ function courseplay:turn(self, dt) --!!!
 					self.cp.waitForTurnTime = self.time + turnOutTimer; 
 				end;
 
+			-- TURN STAGE 6
 			elseif self.cp.turnStage == 6 then
 				self.turnStageTimer = self.turnStageTimer - dt;
 				if self.turnStageTimer < 0 then
@@ -136,6 +160,8 @@ function courseplay:turn(self, dt) --!!!
 			if courseplay.debugChannels[12] then
 				drawDebugPoint(newTargetX, y+3, newTargetZ, 1, 1, 0, 1);
 			end;
+
+		-- TURN STAGE 1
 		elseif self.cp.turnStage == 1 then
 			-- turn
 			local dirX, dirZ = self.aiTractorDirectionX, self.aiTractorDirectionZ;
@@ -159,6 +185,8 @@ function courseplay:turn(self, dt) --!!!
 			self.aiTractorDirectionZ = -dirZ;
 			self.cp.turnStage = 2;
 			self.turnStageTimer = Utils.getNoNil(self.turnStage2Timeout,20000)
+
+		-- TURN STAGE ??? --TODO (Jakob): what's the situation here? turnStage not > 1 and not > 0 ? When do we get to this point?
 		else
 			self.cp.turnStage = 1;
 			if self.cp.noStopOnTurn == false then
@@ -167,6 +195,8 @@ function courseplay:turn(self, dt) --!!!
 			courseplay:lowerImplements(self, false, true)
 			updateWheels = false;
 		end;
+
+	-- TURN STAGE 0
 	else
 		local offset = Utils.getNoNil(self.cp.totalOffsetX, 0)
 		local x,y,z = localToWorld(self.rootNode, offset, 0, backMarker)
@@ -254,7 +284,6 @@ function courseplay:turn(self, dt) --!!!
 		self.aiTractorTargetX = newTargetX;
 		self.aiTractorTargetZ = newTargetZ;
 	end;
-	
 end
 
 function courseplay:lowerImplements(self, direction, workToolonOff)
@@ -304,7 +333,7 @@ function courseplay:turnWithOffset(self)
 	local curPoint = self.Waypoints[self.recordnumber+1]
 	local cx, cz = curPoint.cx, curPoint.cz;
 	local offsetX = self.cp.totalOffsetX
-	if curPoint.turnEnd and curPoint.laneDir ~= nil then
+	if curPoint.turnEnd and curPoint.laneDir ~= nil then --TODO (Jakob): use point's direction to next point to get the proper offset
 		local dir = curPoint.laneDir;
 		local turnDir = curPoint.turn;