三车道驾驶模拟:实现单车道单列与半自动驾驶车道居中控制
Hey there! Let's work through this to get your 3-lane driving simulation set up exactly how you want it—single cars per lane, no overtaking, and solid lane-centering behavior. We'll tweak your existing place-cars-level0 and control-speed code step by step to hit these goals.
Step 1: Modify Vehicle Placement (place-cars-level0)
First, we need to ensure exactly one car per lane instead of random placement. We'll define your 3 lanes per direction, then place one car in each lane with no adjacent cars (to enforce single-file) and disable random turns/stops for predictability.
; place-cars-level0 modified for 3-lane single-car per lane setup to place-cars-level0 ; Define your lane coordinates (adjust these to match your road's actual layout) let road-up-lanes [3 5 7] ; X-coords for 3 upward-moving lanes let road-down-lanes [3 5 7] ; X-coords for 3 downward-moving lanes let road-left-lanes [4 6 8] ; Y-coords for 3 leftward-moving lanes let road-right-lanes [4 6 8] ; Y-coords for 3 rightward-moving lanes ; Place 1 car in each upward lane foreach road-up-lanes [ let lane-x ? ask one-of patches with [meaning = "road-up" and pxcor = lane-x] [ ; Ensure no cars directly ahead/behind, and not near crossings if not any? cars-on patch pxcor (pycor + 1) and not any? cars-here and not any? cars-on patch pxcor (pycor - 1) and not any? patches with [meaning = "crossing"] in-radius 2 [ sprout-cars 1 [ set size 3 set will-turn? "no" ; Disable turns to keep cars in lane set will-stop? "no" ; Disable random stops for consistency set shape "car top" set politeness basic-politeness set heading 0 set maxSpeed speed-limit ; Consistent max speed for semi-autonomous behavior set speed maxSpeed - random 5 ; Slight initial speed variation ] ] ] ] ; Place 1 car in each downward lane foreach road-down-lanes [ let lane-x ? ask one-of patches with [meaning = "road-down" and pxcor = lane-x] [ if not any? cars-on patch pxcor (pycor + 1) and not any? cars-here and not any? cars-on patch pxcor (pycor - 1) and not any? patches with [meaning = "crossing"] in-radius 2 [ sprout-cars 1 [ set size 3 set will-turn? "no" set will-stop? "no" set shape "car top" set politeness basic-politeness set heading 180 set maxSpeed speed-limit set speed maxSpeed - random 5 ] ] ] ] ; Place 1 car in each leftward lane foreach road-left-lanes [ let lane-y ? ask one-of patches with [meaning = "road-left" and pycor = lane-y] [ if not any? cars-on patch (pxcor + 1) pycor and not any? cars-here and not any? cars-on patch (pxcor - 1) pycor and not any? patches with [meaning = "crossing"] in-radius 2 [ sprout-cars 1 [ set size 3 set will-turn? "no" set will-stop? "no" set shape "car top" set politeness basic-politeness set heading 270 set maxSpeed speed-limit set speed maxSpeed - random 5 ] ] ] ] ; Place 1 car in each rightward lane foreach road-right-lanes [ let lane-y ? ask one-of patches with [meaning = "road-right" and pycor = lane-y] [ if not any? cars-on patch (pxcor + 1) pycor and not any? cars-here and not any? cars-on patch (pxcor - 1) pycor and not any? patches with [meaning = "crossing"] in-radius 2 [ sprout-cars 1 [ set size 3 set will-turn? "no" set will-stop? "no" set shape "car top" set politeness basic-politeness set heading 90 set maxSpeed speed-limit set speed maxSpeed - random 5 ] ] ] ] end
Key changes here:
- We explicitly define lanes by coordinate, so each lane gets exactly one car
- Disabled random turns/stops to keep cars in their lanes
- Simplified speed setup for more predictable semi-autonomous behavior
Step 2: Modify Speed Control (control-speed)
Next, we'll strip out all overtaking logic and add lane-centering code. The goal is to keep cars following the vehicle ahead in their lane, with no attempts to pass left/right.
; control-speed modified for lane-keeping and no overtaking to control-speed ; Check for cars directly ahead in the same lane let car-ahead one-of cars-on patch-ahead 4 ; Block overtaking by checking left/right lanes ahead too let car-left-ahead any? cars-on patch-left-and-ahead 90 4 let car-right-ahead any? cars-on patch-right-and-ahead 90 4 ifelse car-ahead = nobody and not car-left-ahead and not car-right-ahead [ ; Accelerate to max speed if we're below it if speed < maxSpeed [ set speed speed + acceleration ] ] [ ; If any car is ahead (same lane or adjacent), match speed to avoid overtaking if [speed] of car-ahead = 0 [ set speed 0 ] else [ ; Stay at or below the lead car's speed, with a small deceleration for safe distance set speed min([speed] of car-ahead, maxSpeed) set speed speed - deceleration ] ] ; Lane-centering logic: keep the car in the middle of its lane ; Adjust these calculations to match your lane width/layout if meaning = "road-up" or meaning = "road-down" [ ; For vertical lanes, calculate the lane's center X-coordinate let lane-center-x round(pxcor / 2) * 2 + 1 ; Drifted left? Move right; drifted right? Move left if pxcor != lane-center-x [ setxy (pxcor + (sign(lane-center-x - pxcor))) pycor ] ] if meaning = "road-left" or meaning = "road-right" [ ; For horizontal lanes, calculate the lane's center Y-coordinate let lane-center-y round(pycor / 2) * 2 + 1 ; Drifted down? Move up; drifted up? Move down if pycor != lane-center-y [ setxy pxcor (pycor + (sign(lane-center-y - pycor))) ] ] end
Key changes here:
- Removed all overtaking/laneswitching code
- Added checks for left/right ahead cars to block any accidental overtaking
- Added lane-centering logic that automatically nudges cars back to the lane center if they drift
Final Integration Tips
- Match Lane Coordinates: Update the
road-up-lanes/etc. variables inplace-cars-level0to match your actual road's pixel coordinates. - Tweak Lane Centering: Adjust the
lane-center-x/lane-center-ycalculations if your lanes are wider/narrower than the example. - Set Car Count: Make sure
num-of-cars-level0is a multiple of 3 (e.g., 3, 6, 9) to match one car per lane.
内容的提问来源于stack exchange,提问作者Tom Best

