Notifications
Clear all

Practicing writing code using Python

4 Posts
3 Users
0 Reactions
99 Views
robotBuilder
(@robotbuilder)
Member
Joined: 6 years ago
Posts: 2325
Topic starter  

@byron

Practicing writing Python versions of my FreeBASIC code so it can be shared with a wider audience.

Just as an exercise I wrote a Python version of the neural net simulation robot I was playing with in this thread.

https://forum.dronebotworkshop.com/neural-networks/genetic-evolution-of-a-neural-network-driven-robot/paged/8/

Although @thrandell uses C++ I don't actually know how to install a simple graphics library with a simple C++ compiler to write C++ version.

Although I have FreeBASIC version using the Genetic Algorithm to find a set of working weights I have left it out in this example to keep it simple. The sketch requires the attached image plan2B.png which I happen to store in C:/BITMAPS/ so that line would have to be changed.

plan2B

 

import numpy as np
import pygame
import math

# Sigmoid function
def sigmoid(X):
    return 1 / (1 + np.exp(-X)) - 0.5

# Constants
Pi = 4 * math.atan(1)
TwoPi = 8 * math.atan(1)
RtoD = 180 / Pi   # radians to degrees
DtoR = Pi / 180   # degrees to radians

# Constants for the world dimensions
WORLDX = 800
WORLDY = 440

# Initialize Pygame
pygame.init()
screen = pygame.display.set_mode((WORLDX, WORLDY))
pygame.display.set_caption('Robot Simulation')
clock = pygame.time.Clock()

# Load bitmap image
plan = pygame.image.load('C:/BITMAPS/plan2B.png').convert()
path_color = (255, 0, 255)

# Robot variables
ox, oy = 45.0, 45.0  # Initial robot position
rr = 12           # Robot radius
SL, SR = 0.0, 0.0     # Wheel speeds
theta = 0.0 * DtoR      # Direction in radians

# Initialize distance inputs and weights

d = np.zeros(8)
w1 = np.zeros(8)
w2 = np.zeros(8)

RED = (200,50,0)

colors = [
    (255, 0, 0),
    (0, 255, 0),
    (0, 0, 255),
    (255, 255, 0),
    (255, 0, 200),
    (127, 0, 0),
    (0, 127, 0),
    (0, 0, 127)
]

# Function to shoot rays from the robot's position
def shoot_ray(x1, y1, angle, cc):
    dx = math.cos(angle)
    dy = math.sin(angle)
    
    x, y = x1, y1

    if abs(dx) > abs(dy):
        change = abs(dy) / abs(dx)
        aa = 1 if dx >= 0 else -1
        if dy < 0:
            change = -change
        while 0 <= int(x) < WORLDX and 0 <= int(y) < WORLDY and plan.get_at((int(x), int(y))) == (255, 255, 255):
            x += aa
            y += change
            pygame.draw.circle(screen, cc, (int(x), int(y)), 1)
            pygame.draw.circle(path, (100,100,0), (ox, oy), 2)
    else:
        change = abs(dx) / abs(dy)
        aa = 1 if dy >= 0 else -1
        if dx < 0:
            change = -change
        while 0 <= int(x) < WORLDX and 0 <= int(y) < WORLDY and plan.get_at((int(x), int(y))) == (255, 255, 255):
            y += aa
            x += change
            pygame.draw.circle(screen, cc, (int(x), int(y)), 1)
            pygame.draw.circle(path, (100,100,0), (ox, oy), 2)
            

    distance = math.sqrt((ox - x) ** 2 + (oy - y) ** 2)
    
    if (0 <= int(x) < WORLDX and 0 <= int(y) < WORLDY):
        if plan.get_at((int(x), int(y))) != (255, 255, 255):
            pygame.draw.circle(screen, (255, 255, 0), (int(x), int(y)), 2)  # Yellow hit

    return distance

# Function to move the robot
def move_robot():
    global ox, oy, theta
    w = 150  # width of wheel   
    if SL == SR:
        # Moving in a straight line 
        ox += SL * math.cos(theta)
        oy += SL * math.sin(theta)
    else:
        # Moving in an arc 
        expr1 = w * (SR + SL) / 2.0 / (SR - SL)
        ox += expr1 * (math.sin((SR - SL) / w + theta) - math.sin(theta))
        oy -= expr1 * (math.cos((SR - SL) / w + theta) - math.cos(theta))
        theta += (SR - SL) / w

        # Keep in the range -Pi to +Pi 
        if theta > Pi:
            theta -= 2.0 * Pi
        if theta < -Pi:
            theta += 2.0 * Pi

# Main loop
rays = pygame.Surface((WORLDX, WORLDY), pygame.SRCALPHA) # not used
path = pygame.Surface((WORLDX, WORLDY), pygame.SRCALPHA)



running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill((0, 0, 0))  # Clear screen
    screen.blit(plan, (0, 0)) # copy image "plan" to screen
    #rays.fill((255, 0, 255, 0))  # Clear ray surface
    
    cc = 0


    for i in range(8):
        distance = shoot_ray(ox,oy,(( i * (45*DtoR) ) + theta ),colors[i])               
        d[i] = distance / 100



    # Control for robot movement

    #compute output value of neurons outputs
    #working weights are supposed to be evolved but I have left that out
    #and simply selected weights I could see would sort of work just to
    #demo the simulated robot.

    w1[0]=0.5
    w2[0]=0.5
  
    w1[1]= -0.5
    w2[1]=  0.5
  
    w1[2] = -0.5
    w2[2] = 0.5

    w1[3] = 0.0
    w2[3] = 0.0

    w1[4] = 0.0
    w2[4] = 0.0

    w1[5] = 0.0
    w2[5] = 0.0
  
    w1[6] = 0.5
    w2[6] = -0.5
    
    w1[7] = 0.5
    w2[7] = -0.5

    SL = 0
    SR = 0
    
    for i in range(8):
        SL = SL + d[i] * w1[i]
        SR = SR + d[i] * w2[i]
    
    move_robot()

    # Display robot (circle) position
    pygame.draw.circle(screen, (12, 12, 200), (int(ox), int(oy)), rr)
    xd = math.cos(theta) * rr
    yd = math.sin(theta) * rr
    pygame.draw.line(screen, (20, 20, 20), (int(ox), int(oy)), (int(ox + xd), int(oy + yd)), 1)

    # Check for collisions
    hit = sum(1 for angle in range(360) if plan.get_at((int(ox + rr * math.cos(angle * DtoR)), int(oy + rr * math.sin(angle * DtoR)))) == (0, 0, 0))

    if hit > 0:
        ox -= math.cos(theta) * 5  # Back off a bit
        oy -= math.sin(theta) * 5  # Back off a bit

    # Update display
    screen.blit(rays, (0, 0))
    # Blit the path surface onto the screen with transparency
    screen.blit(path, (0, 0))

    #print (SL,SR)
    
    pygame.display.flip()
    clock.tick(60)  # Set frame rate (60 FPS)

pygame.quit()


 

 


   
Quote
byron
(@byron)
No Title
Joined: 6 years ago
Posts: 1212
 

@robotbuilder  I think I will have to create a robo folder on my new mac for your snippets.  That spidery thing finds its way around the grid rather nicely.   Your python skills are doing well. 😀

 

 


   
ReplyQuote
(@aliarifat)
Member
Joined: 8 months ago
Posts: 60
 

Posted by: @robotbuilder

@byron

Practicing writing Python versions of my FreeBASIC code so it can be shared with a wider audience.

Just as an exercise I wrote a Python version of the neural net simulation robot I was playing with in this thread.

https://forum.dronebotworkshop.com/neural-networks/genetic-evolution-of-a-neural-network-driven-robot/paged/8/

Although @thrandell uses C++ I don't actually know how to install a simple graphics library with a simple C++ compiler to write C++ version.

Although I have FreeBASIC version using the Genetic Algorithm to find a set of working weights I have left it out in this example to keep it simple. The sketch requires the attached image plan2B.png which I happen to store in C:/BITMAPS/ so that line would have to be changed.

-- attachment is not available --

 

import numpy as np
import pygame
import math

# Sigmoid function
def sigmoid(X):
    return 1 / (1 + np.exp(-X)) - 0.5

# Constants
Pi = 4 * math.atan(1)
TwoPi = 8 * math.atan(1)
RtoD = 180 / Pi   # radians to degrees
DtoR = Pi / 180   # degrees to radians

# Constants for the world dimensions
WORLDX = 800
WORLDY = 440

# Initialize Pygame
pygame.init()
screen = pygame.display.set_mode((WORLDX, WORLDY))
pygame.display.set_caption('Robot Simulation')
clock = pygame.time.Clock()

# Load bitmap image
plan = pygame.image.load('C:/BITMAPS/plan2B.png').convert()
path_color = (255, 0, 255)

# Robot variables
ox, oy = 45.0, 45.0  # Initial robot position
rr = 12           # Robot radius
SL, SR = 0.0, 0.0     # Wheel speeds
theta = 0.0 * DtoR      # Direction in radians

# Initialize distance inputs and weights

d = np.zeros(8)
w1 = np.zeros(8)
w2 = np.zeros(8)

RED = (200,50,0)

colors = [
    (255, 0, 0),
    (0, 255, 0),
    (0, 0, 255),
    (255, 255, 0),
    (255, 0, 200),
    (127, 0, 0),
    (0, 127, 0),
    (0, 0, 127)
]

# Function to shoot rays from the robot's position
def shoot_ray(x1, y1, angle, cc):
    dx = math.cos(angle)
    dy = math.sin(angle)
    
    x, y = x1, y1

    if abs(dx) > abs(dy):
        change = abs(dy) / abs(dx)
        aa = 1 if dx >= 0 else -1
        if dy < 0:
            change = -change
        while 0 <= int(x) < WORLDX and 0 <= int(y) < WORLDY and plan.get_at((int(x), int(y))) == (255, 255, 255):
            x += aa
            y += change
            pygame.draw.circle(screen, cc, (int(x), int(y)), 1)
            pygame.draw.circle(path, (100,100,0), (ox, oy), 2)
    else:
        change = abs(dx) / abs(dy)
        aa = 1 if dy >= 0 else -1
        if dx < 0:
            change = -change
        while 0 <= int(x) < WORLDX and 0 <= int(y) < WORLDY and plan.get_at((int(x), int(y))) == (255, 255, 255):
            y += aa
            x += change
            pygame.draw.circle(screen, cc, (int(x), int(y)), 1)
            pygame.draw.circle(path, (100,100,0), (ox, oy), 2)
            

    distance = math.sqrt((ox - x) ** 2 + (oy - y) ** 2)
    
    if (0 <= int(x) < WORLDX and 0 <= int(y) < WORLDY):
        if plan.get_at((int(x), int(y))) != (255, 255, 255):
            pygame.draw.circle(screen, (255, 255, 0), (int(x), int(y)), 2)  # Yellow hit

    return distance

# Function to move the robot
def move_robot():
    global ox, oy, theta
    w = 150  # width of wheel   
    if SL == SR:
        # Moving in a straight line 
        ox += SL * math.cos(theta)
        oy += SL * math.sin(theta)
    else:
        # Moving in an arc 
        expr1 = w * (SR + SL) / 2.0 / (SR - SL)
        ox += expr1 * (math.sin((SR - SL) / w + theta) - math.sin(theta))
        oy -= expr1 * (math.cos((SR - SL) / w + theta) - math.cos(theta))
        theta += (SR - SL) / w

        # Keep in the range -Pi to +Pi 
        if theta > Pi:
            theta -= 2.0 * Pi
        if theta < -Pi:
            theta += 2.0 * Pi

# Main loop
rays = pygame.Surface((WORLDX, WORLDY), pygame.SRCALPHA) # not used
path = pygame.Surface((WORLDX, WORLDY), pygame.SRCALPHA)



running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill((0, 0, 0))  # Clear screen
    screen.blit(plan, (0, 0)) # copy image "plan" to screen
    #rays.fill((255, 0, 255, 0))  # Clear ray surface
    
    cc = 0


    for i in range(8):
        distance = shoot_ray(ox,oy,(( i * (45*DtoR) ) + theta ),colors[i])               
        d[i] = distance / 100



    # Control for robot movement

    #compute output value of neurons outputs
    #working weights are supposed to be evolved but I have left that out
    #and simply selected weights I could see would sort of work just to
    #demo the simulated robot.

    w1[0]=0.5
    w2[0]=0.5
  
    w1[1]= -0.5
    w2[1]=  0.5
  
    w1[2] = -0.5
    w2[2] = 0.5

    w1[3] = 0.0
    w2[3] = 0.0

    w1[4] = 0.0
    w2[4] = 0.0

    w1[5] = 0.0
    w2[5] = 0.0
  
    w1[6] = 0.5
    w2[6] = -0.5
    
    w1[7] = 0.5
    w2[7] = -0.5

    SL = 0
    SR = 0
    
    for i in range(8):
        SL = SL + d[i] * w1[i]
        SR = SR + d[i] * w2[i]
    
    move_robot()

    # Display robot (circle) position
    pygame.draw.circle(screen, (12, 12, 200), (int(ox), int(oy)), rr)
    xd = math.cos(theta) * rr
    yd = math.sin(theta) * rr
    pygame.draw.line(screen, (20, 20, 20), (int(ox), int(oy)), (int(ox + xd), int(oy + yd)), 1)

    # Check for collisions
    hit = sum(1 for angle in range(360) if plan.get_at((int(ox + rr * math.cos(angle * DtoR)), int(oy + rr * math.sin(angle * DtoR)))) == (0, 0, 0))

    if hit > 0:
        ox -= math.cos(theta) * 5  # Back off a bit
        oy -= math.sin(theta) * 5  # Back off a bit

    # Update display
    screen.blit(rays, (0, 0))
    # Blit the path surface onto the screen with transparency
    screen.blit(path, (0, 0))

    #print (SL,SR)
    
    pygame.display.flip()
    clock.tick(60)  # Set frame rate (60 FPS)

pygame.quit()


 

 

What did you use to write the python script? I use IDLE 3.12.

 


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 6 years ago
Posts: 2325
Topic starter  

@aliarifat 

Yes I use IDLE 3.12 no fancy editor.

 


   
ReplyQuote