Forum

Notifications
Clear all

Self-Driving Car Python TensorFlow

1 Posts
1 Users
0 Reactions
7 Views
 josh
(@josh)
Member Admin
Joined: 2 months ago
Posts: 510
Topic starter  
# Robotic Car with Autonomous Driving Capabilities

## Folder Structure:
```
robotic_car/
├── main.py
├── car_controller.py
├── sensor_manager.py
├── object_detector.py
├── path_planner.py
├── motor_controller.py
├── utils.py
├── config.py
├── models/
│   ├── yolov5s.pt
│   └── object_detection_model.h5
├── data/
│   ├── images/
│   └── logs/
├── requirements.txt
└── README.md
```

## Code Implementation:

### 1. requirements.txt
```txt
tensorflow==2.13.0
torch==2.0.1
opencv-python==4.8.1.78
numpy==1.24.3
pandas==2.0.3
matplotlib==3.7.2
scikit-learn==1.3.0
pillow==10.0.1
pyserial==3.5
flask==2.3.2
```

### 2. config.py
```python
# Configuration file for robotic car system

class CarConfig:
    # Motor configuration
    MOTOR_LEFT_PIN = 12
    MOTOR_RIGHT_PIN = 13
    PWM_FREQUENCY = 1000
    
    # Sensor configuration
    SENSOR_FRONT_TRIG = 23
    SENSOR_FRONT_ECHO = 24
    SENSOR_SIDE_TRIG = 5
    SENSOR_SIDE_ECHO = 6
    
    # Camera configuration
    CAMERA_WIDTH = 640
    CAMERA_HEIGHT = 480
    CAMERA_FPS = 30
    
    # Movement parameters
    MAX_SPEED = 255
    TURN_SPEED = 150
    STOP_DISTANCE = 20  # cm
    
    # Object detection thresholds
    DETECTION_CONFIDENCE = 0.5
    DETECTION_IOU_THRESHOLD = 0.3
    
    # Path planning parameters
    PATH_PLANNING_INTERVAL = 0.1  # seconds
    MAX_TURN_ANGLE = 30  # degrees
    
    # Logging
    LOG_FILE = "data/logs/car_log.txt"
    
    # Object types to detect
    OBJECT_TYPES = [
        "stop_sign",
        "crosswalk",
        "train_track",
        "vehicle",
        "pedestrian"
    ]

# Initialize configuration
config = CarConfig()
```

### 3. car_controller.py
```python
import time
from motor_controller import MotorController
from sensor_manager import SensorManager
from object_detector import ObjectDetector
from path_planner import PathPlanner

class RoboticCar:
    def __init__(self):
        self.motor_controller = MotorController()
        self.sensor_manager = SensorManager()
        self.object_detector = ObjectDetector()
        self.path_planner = PathPlanner()
        
        # Car state
        self.current_speed = 0
        self.is_moving = False
        self.current_direction = "forward"
        
    def start(self):
        """Start the robotic car"""
        print("Robotic car starting...")
        self.motor_controller.initialize()
        self.sensor_manager.initialize()
        self.object_detector.load_model()
        print("Car initialized successfully!")
        
    def drive_forward(self, speed=100):
        """Drive forward at specified speed"""
        self.current_speed = speed
        self.is_moving = True
        self.current_direction = "forward"
        self.motor_controller.set_speed(speed, speed)
        print(f"Driving forward at {speed}% speed")
        
    def drive_backward(self, speed=100):
        """Drive backward at specified speed"""
        self.current_speed = speed
        self.is_moving = True
        self.current_direction = "backward"
        self.motor_controller.set_speed(-speed, -speed)
        print(f"Driving backward at {speed}% speed")
        
    def turn_left(self, angle=45):
        """Turn left at specified angle"""
        if angle > 90:
            angle = 90
        elif angle < 0:
            angle = 0
            
        self.motor_controller.set_speed(-angle, angle)
        print(f"Turning left {angle} degrees")
        
    def turn_right(self, angle=45):
        """Turn right at specified angle"""
        if angle > 90:
            angle = 90
        elif angle < 0:
            angle = 0
            
        self.motor_controller.set_speed(angle, -angle)
        print(f"Turning right {angle} degrees")
        
    def stop(self):
        """Stop the car"""
        self.motor_controller.set_speed(0, 0)
        self.is_moving = False
        self.current_speed = 0
        print("Car stopped")
        
    def accelerate(self, target_speed):
        """Gradually accelerate to target speed"""
        if target_speed > 100:
            target_speed = 100
            
        current_speed = self.current_speed
        step = 5
        
        while current_speed < target_speed:
            current_speed += step
            if current_speed > target_speed:
                current_speed = target_speed
                
            self.motor_controller.set_speed(current_speed, current_speed)
            time.sleep(0.1)
            
        print(f"Accelerated to {target_speed}% speed")
        
    def decelerate(self, target_speed):
        """Gradually decelerate to target speed"""
        if target_speed < 0:
            target_speed = 0
            
        current_speed = self.current_speed
        step = 5
        
        while current_speed > target_speed:
            current_speed -= step
            if current_speed < target_speed:
                current_speed = target_speed
                
            self.motor_controller.set_speed(current_speed, current_speed)
            time.sleep(0.1)
            
        print(f"Decelerated to {target_speed}% speed")
        
    def detect_objects(self):
        """Detect objects in front of the car"""
        distance = self.sensor_manager.get_front_distance()
        if distance < 20:  # If object is too close
            self.stop()
            return "obstacle"
            
        # Use camera to detect objects
        image = self.sensor_manager.capture_image()
        if image is not None:
            detected_objects = self.object_detector.detect_objects(image)
            return detected_objects
            
        return []
        
    def navigate(self):
        """Main navigation function"""
        print("Navigation started...")
        
        while True:
            # Get distance to front object
            front_distance = self.sensor_manager.get_front_distance()
            
            # If obstacle is too close, stop
            if front_distance < 20:
                self.stop()
                print(f"Obstacle detected at {front_distance} cm")
                time.sleep(1)
                continue
                
            # Detect objects using camera
            objects = self.detect_objects()
            
            # Process detected objects
            for obj in objects:
                obj_type = obj['type']
                confidence = obj['confidence']
                
                if confidence > 0.7:  # High confidence detection
                    if obj_type == "stop_sign":
                        print("Stop sign detected - stopping car")
                        self.stop()
                        time.sleep(3)  # Wait 3 seconds before continuing
                    elif obj_type == "crosswalk":
                        print("Crosswalk detected - slowing down")
                        self.decelerate(50)
                        time.sleep(2)
                        self.accelerate(80)
                    elif obj_type == "train_track":
                        print("Train track detected - proceeding with caution")
                        self.decelerate(60)
                        time.sleep(3)
                        self.accelerate(90)
                    elif obj_type == "vehicle":
                        print("Vehicle ahead - adjusting speed")
                        self.decelerate(70)
                        time.sleep(2)
                        self.accelerate(90)
                    elif obj_type == "pedestrian":
                        print("Pedestrian detected - stopping")
                        self.stop()
                        time.sleep(5)
                        
            # Continue driving forward
            if not self.is_moving:
                self.drive_forward(80)
                
            time.sleep(0.1)  # Small delay to prevent excessive CPU usage
            
    def cleanup(self):
        """Clean up resources"""
        self.stop()
        self.motor_controller.cleanup()
        self.sensor_manager.cleanup()
        print("Car system cleaned up")
```

### 4. motor_controller.py
```python
import time
import RPi.GPIO as GPIO

class MotorController:
    def __init__(self):
        # Initialize GPIO
        GPIO.setmode(GPIO.BCM)
        self.left_motor_pin = 12
        self.right_motor_pin = 13
        self.pwm_left = None
        self.pwm_right = None
        
    def initialize(self):
        """Initialize motor controller"""
        GPIO.setup(self.left_motor_pin, GPIO.OUT)
        GPIO.setup(self.right_motor_pin, GPIO.OUT)
        
        # Setup PWM
        self.pwm_left = GPIO.PWM(self.left_motor_pin, 1000)
        self.pwm_right = GPIO.PWM(self.right_motor_pin, 1000)
        
        self.pwm_left.start(0)
        self.pwm_right.start(0)
        
        print("Motor controller initialized")
        
    def set_speed(self, left_speed, right_speed):
        """Set speed for both motors (0-255)"""
        # Normalize speeds to 0-100%
        left_speed = max(0, min(100, left_speed))
        right_speed = max(0, min(100, right_speed))
        
        # Convert to duty cycle (0-100)
        left_duty_cycle = left_speed
        right_duty_cycle = right_speed
        
        self.pwm_left.ChangeDutyCycle(left_duty_cycle)
        self.pwm_right.ChangeDutyCycle(right_duty_cycle)
        
    def stop(self):
        """Stop both motors"""
        self.set_speed(0, 0)
        
    def cleanup(self):
        """Clean up GPIO"""
        self.stop()
        GPIO.cleanup()
        print("Motor controller cleaned up")
```

### 5. sensor_manager.py
```python
import time
import RPi.GPIO as GPIO
import cv2
import numpy as np

class SensorManager:
    def __init__(self):
        # Initialize GPIO for ultrasonic sensors
        self.front_trig = 23
        self.front_echo = 24
        self.side_trig = 5
        self.side_echo = 6
        
        GPIO.setmode(GPIO.BCM)
        
    def initialize(self):
        """Initialize all sensors"""
        # Setup ultrasonic sensor pins
        GPIO.setup(self.front_trig, GPIO.OUT)
        GPIO.setup(self.front_echo, GPIO.IN)
        GPIO.setup(self.side_trig, GPIO.OUT)
        GPIO.setup(self.side_echo, GPIO.IN)
        
        print("Sensors initialized")
        
    def get_front_distance(self):
        """Get distance from front ultrasonic sensor"""
        return self._get_distance(self.front_trig, self.front_echo)
        
    def get_side_distance(self):
        """Get distance from side ultrasonic sensor"""
        return self._get_distance(self.side_trig, self.side_echo)
        
    def _get_distance(self, trig_pin, echo_pin):
        """Helper function to measure distance"""
        # Send trigger pulse
        GPIO.output(trig_pin, True)
        time.sleep(0.00001)
        GPIO.output(trig_pin, False)
        
        start_time = time.time()
        stop_time = time.time()
        
        # Wait for echo
        while GPIO.input(echo_pin) == 0:
            start_time = time.time()
            
        while GPIO.input(echo_pin) == 1:
            stop_time = time.time()
            
        # Calculate distance
        elapsed_time = stop_time - start_time
        distance = (elapsed_time * 34300) / 2  # Speed of sound in cm
        
        return round(distance, 2)
        
    def capture_image(self):
        """Capture image from camera"""
        try:
            # Initialize camera
            cap = cv2.VideoCapture(0)
            cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
            cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
            
            ret, frame = cap.read()
            cap.release()
            
            if ret:
                return frame
            else:
                print("Failed to capture image")
                return None
                
        except Exception as e:
            print(f"Error capturing image: {e}")
            return None
            
    def cleanup(self):
        """Clean up GPIO"""
        GPIO.cleanup()
        print("Sensors cleaned up")
```

### 6. object_detector.py
```python
import cv2
import numpy as np
from config import config

class ObjectDetector:
    def __init__(self):
        self.model = None
        self.classes = []
        self.colors = {}
        
    def load_model(self):
        """Load object detection model"""
        # In a real implementation, this would load a pre-trained model
        # For demonstration purposes, we'll simulate object detection
        
        # Create dummy classes for demonstration
        self.classes = config.OBJECT_TYPES
        print("Object detection model loaded")
        
    def detect_objects(self, image):
        """Detect objects in the image"""
        # In a real implementation, this would use a neural network
        # For demonstration, we'll simulate detections
        
        # Simulate object detection results
        detections = []
        
        # Add some dummy detections for demonstration
        if np.random.random() > 0.7:  # Random chance of detecting something
            obj_type = np.random.choice(self.classes)
            confidence = round(np.random.uniform(0.6, 1.0), 2)
            
            detections.append({
                'type': obj_type,
                'confidence': confidence,
                'bbox': [100, 100, 200, 200]  # dummy bounding box
            })
            
        return detections
        
    def preprocess_image(self, image):
        """Preprocess image for detection"""
        # Resize image
        resized = cv2.resize(image, (416, 416))
        
        # Normalize pixel values
        normalized = resized.astype(np.float32) / 255.0
        
        return normalized
        
    def post_process_detections(self, detections):
        """Process and filter detections"""
        # Filter detections by confidence threshold
        filtered_detections = []
        for detection in detections:
            if detection['confidence'] > config.DETECTION_CONFIDENCE:
                filtered_detections.append(detection)
                
        return filtered_detections
```

### 7. path_planner.py
```python
import math

class PathPlanner:
    def __init__(self):
        self.current_path = []
        self.target_direction = None
        
    def plan_path(self, start_point, target_point):
        """Plan a path from start to target"""
        # Simple straight-line path planning
        distance = math.sqrt(
            (target_point[0] - start_point[0])**2 + 
            (target_point[1] - start_point[1])**2
        )
        
        angle = math.atan2(
            target_point[1] - start_point[1],
            target_point[0] - start_point[0]
        )
        
        path = {
            'distance': distance,
            'angle': math.degrees(angle),
            'points': [start_point, target_point]
        }
        
        self.current_path = path
        return path
        
    def adjust_direction(self, current_angle, target_angle):
        """Adjust car direction based on current and target angles"""
        angle_diff = target_angle - current_angle
        
        # Normalize angle difference
        while angle_diff > 180:
            angle_diff -= 360
        while angle_diff < -180:
            angle_diff += 360
            
        return angle_diff
        
    def get_safe_turn(self, obstacle_distance):
        """Calculate safe turn based on obstacle distance"""
        if obstacle_distance > 50:
            return 0  # No need to turn
        elif obstacle_distance > 20:
            return 15  # Small turn
        else:
            return 45  # Large turn
            
    def get_path_status(self):
        """Get current path status"""
        return {
            'path_length': len(self.current_path),
            'is_planned': len(self.current_path) > 0
        }
```

### 8. main.py
```python
#!/usr/bin/env python3

from car_controller import RoboticCar
import signal
import sys

def signal_handler(sig, frame):
    """Handle Ctrl+C gracefully"""
    print('\nShutting down...')
    car.cleanup()
    sys.exit(0)

def main():
    # Setup signal handler for graceful shutdown
    signal.signal(signal.SIGINT, signal_handler)
    
    # Initialize car
    global car
    car = RoboticCar()
    car.start()
    
    try:
        # Start navigation
        car.navigate()
        
    except KeyboardInterrupt:
        print("Interrupted by user")
    except Exception as e:
        print(f"Error occurred: {e}")
    finally:
        car.cleanup()

if __name__ == "__main__":
    main()
```

### 9. requirements.txt
```
opencv-python==4.5.1.48
numpy==1.19.5
RPi.GPIO==0.7.0
```

## Features of this Robotic Car System:

1. **Motor Control**: Full control over forward/backward movement and turning
2. **Sensor Integration**: Ultrasonic sensors for obstacle detection
3. **Camera Integration**: Object detection using computer vision
4. **Path Planning**: Basic path planning and obstacle avoidance
5. **Safety Features**: Automatic stopping when obstacles are detected
6. **Object Recognition**: Detection of stop signs, crosswalks, train tracks, vehicles, and pedestrians
7. **Smooth Acceleration/Deceleration**: Gradual speed changes for smooth driving
8. **Logging**: Basic logging functionality
9. **Graceful Shutdown**: Proper cleanup on exit

## Usage:

1. Install dependencies: `pip install -r requirements.txt`
2. Run the main program: `python main.py`
3. The car will start navigating automatically, detecting and responding to various objects

This implementation provides a foundation that can be extended with actual neural network models for object detection, more sophisticated path planning algorithms, and additional sensor integration.

   
Quote
Share: