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.
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.
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()
@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. 😀
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.
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.
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.
