Commit a6b73d60 authored by dave griffiths's avatar dave griffiths

added pattern matrix stuff

parent 32eb4f24
# invisible driver...
import RPi.GPIO as io
import time
def quick_setup(pins,i):
for pin in pins:
io.setup(pin,i)
def quick_set(pins,v):
debug = ""
for i in range(0,len(pins)):
debug+=str((v>>i)&1)
#if pins[i]==3:
# print(str(pins[i])+":"+str((v>>i)&1))
#time.sleep(0.1)
io.output(pins[i],(v>>i)&1)
#print(debug)
def quick_read(pins):
for i in range(0,len(pins)):
t = io.input(pins[i])
print("pin "+str(i)+" is "+str(t))
def value_read(pins):
v = 0
for i in range(0,len(pins)):
# low is 1, pull up resistor
t = not io.input(pins[i])
#print("pin:"+str(pins[i])+" is "+str(io.input(pins[i])))
v |= t<<i
return v
def value_read_inverse(pins):
v = 0
for i in range(0,len(pins)):
# low is 1, pull up resistor
t = not io.input(pins[len(pins)-i-1])
v |= t<<i
return v
value_pins = [7,8,25,24,23,18,15,14]
address_pins = [27,17,4,3,2]
def read_addr(addr):
quick_set(address_pins, addr)
return value_read(value_pins)
def read_addr_4bit(addr):
quick_set(address_pins, addr)
# flip addr zero due to plug hw error
if addr==0 or addr==1:
if addr%2==0:
return (value_read_inverse(value_pins)>>4) & 0x0f
else:
return value_read_inverse(value_pins) & 0x0f
if addr%2==0:
return (value_read(value_pins)>>4) & 0x0f
else:
return value_read(value_pins) & 0x0f
def read_code():
r = []
for i in range(0,16):
r.append(read_addr(i))
return r
def init():
try:
io.setmode(io.BCM)
quick_setup(value_pins, io.IN)
quick_setup(address_pins, io.OUT)
quick_set(address_pins, 0)
except:
print "error"
def read_all():
ret = []
for addr in range(0,32):
ret.append(read_addr_4bit(addr))
return ret
def read_addr(addr):
return read_addr_4bit(addr)
# ======================================================================
# file: OSC.py
# author: stefan kersten <steve@k-hornz.de>
# contents: OSC client module for python
# license: public domain
# ======================================================================
# $Id: osc.py,v 1.1 2006/01/25 10:42:53 nebogeo Exp $
# ======================================================================
# copyright (c) 2000 stefan kersten
# ======================================================================
# this module provides simple OSC client functionality
# usage examples down at the end of the file
# ======================================================================
__revision__ = "$Revision: 1.1 $"
# ======================================================================
# imports
import cStringIO, exceptions, math, socket, struct, time, types
# ======================================================================
# constants
SECONDS_UTC_TO_UNIX_EPOCH = 2208988800.0
FLOAT_TO_INT_SCALE = pow(2.0, 32.0)
# ======================================================================
# types
class Value:
"""Abstract OSC value."""
def __init__(self, value):
self.value = value
def binary_value(self):
pass
def type_tag(self):
pass
class Int(Value):
"""32 bit integer value."""
def __init__(self, value):
Value.__init__(self, long(value))
def binary_value(self):
return struct.pack('!l', self.value)
def type_tag(self):
return 'i'
class Float(Value):
"""32 bit floating point value."""
def __init__(self, value):
Value.__init__(self, float(value))
def binary_value(self):
return struct.pack('!f', self.value)
def type_tag(self):
return 'f'
class String(Value):
"""Null-terminated string padded to multiples of 4 byte."""
def __init__(self, value):
Value.__init__(self, str(value))
def binary_value(self):
v = self.value
l = len(v)
return struct.pack('%ds%dx' % (l, self.pad_amount(l)), v)
def type_tag(self):
return 's'
def pad_amount(self, len):
return 4 - (len % 4)
class Time(Value):
"""64 bit timetag in NTP format."""
def __init__(self, value):
Value.__init__(self, float(value))
def __add__(self, time):
return Time(float(self.value + time.value))
def binary_value(self):
t = self.value
# FIXME: how to convert without overflows?
s = long(t)
f = long(math.fmod(t, 1.0)*FLOAT_TO_INT_SCALE)
return struct.pack('!LL', s, f)
# ======================================================================
# utilities
time_module = time
def time():
"""Return current time as float in OSC format."""
return SECONDS_UTC_TO_UNIX_EPOCH + time_module.time()
# ======================================================================
# classes
class Packet:
"""Abstract base class for all OSC-related containers.
Has methods for retrieving the proper binary representation
and its size.
"""
def __init__(self, packets):
stream = cStringIO.StringIO()
self._write_contents(packets, stream)
self._data = stream.getvalue()
def get_packet(self):
"""Return the binary representation of the receiver's contents.
This data is in the proper OSC format and can be sent over a
socket.
"""
return self._data
def get_size(self):
"""Return the size of the receiver's binary data."""
return len(self._data)
def _write_contents(self, packets, stream):
"""Write packets on stream.
Private.
Override in subclasses for specific behavior.
"""
pass
def __repr__(self):
return '<' + \
str(self.__class__.__name__) + \
' instance, size=' + \
str(self.get_size()) + \
'>'
def sendto(self, host, port):
"""Send the receiver's data through a UDP socket."""
s = socket.socket(socket.SOCK_DGRAM, socket.AF_INET)
packet = self.get_packet()
s.sendto(packet, (host, port))
s.close()
def sendlocal(self, port):
"""Send the receiver's data through a UDP socket locally."""
self.sendto('localhost', port)
def _value(x):
"""Convert x(int, float or string) to an OSC object."""
t = type(x)
if t == types.FloatType:
return Float(x)
if t == types.IntType or t == types.LongType:
return Int(x)
# return string representation as default
return String(str(x))
class Message(Packet):
"""Single OSC message with arguments.
Message(address, *args) -> Message
address -- OSC address string
*args -- message argument list
"""
def __init__(self, address, args=[]):
Packet.__init__(self, [String(address)] + map(lambda x: _value(x), args))
def _write_contents(self, args, stream):
t_stream = cStringIO.StringIO() # tag stream
v_stream = cStringIO.StringIO() # value stream
# open signature string
t_stream.write(',')
# collect tags and arguments
for v in args[1:]:
t_stream.write(v.type_tag())
v_stream.write(v.binary_value())
# write address
stream.write(args[0].binary_value())
# write signature
stream.write(String(t_stream.getvalue()).binary_value())
# write arguments
stream.write(v_stream.getvalue())
class Bundle(Packet):
"""OSC container type with timing information.
Bundle(time, packets) -> Bundle
time -- floating point timetag in OSC units
packets -- array of Packet(s)
"""
def __init__(self, time, packets):
Packet.__init__(self, [Time(time)] + packets)
def _write_contents(self, args, stream):
# write '#bundle' preamble
stream.write(String('#bundle').binary_value())
# write timetag
stream.write(args[0].binary_value())
# write packets, prefixed with a byte count
for packet in args[1:]:
data = packet.get_packet()
size = len(data)
stream.write(Int(size).binary_value())
stream.write(data)
def test(port):
"""Some example messages and bundles, sent to port."""
Message("/filter/cutoff", [145.1232]).sendlocal(port)
Message("/http", ["www dot k-hornz dot de", 12, 3.41, "bulb"]).sendlocal(port)
# print Int(len(Message("/msg").get_packet())).binary_value()
Bundle(0.1, [Message("/fubar")]).sendlocal(port)
Bundle(time(), [Message("/msg", [1.0, "+", 1, 61, "0"]), Message("/bang!")]).sendlocal(port)
def test2():
"""Some example messages and bundles, sent to port."""
Message("/noisepattern/start", ["hello"]).sendlocal(9898989)
Message("/noisepattern/modify", [1, "hello", "two"]).sendlocal(9898989)
print("/noisepattern/start")
if __name__ == "__main__":
"""Run dump on port 10000."""
#test(10000)
test2()
# EOF
# ======================================================================
import driver
import time
import osc
driver.init()
print(driver.read_all())
def send_weave_structure(blocks):
weave = [blocks[0],blocks[1],blocks[2],blocks[3],
blocks[8],blocks[9],blocks[10],blocks[11],
blocks[16],blocks[17],blocks[18],blocks[19],
blocks[24],blocks[25],blocks[26],blocks[27]]
conv = reduce(lambda r,e: r+"0 " if e==0 else r+"1 ",
weave,"")
osc.Message("/eval",["(with-primitive warp \n (write-into-executable! \n warp-draft-start \n (list "+conv+")))\n"+
"(with-primitive weft \n (write-into-executable! \n weft-draft-start \n (list "+conv+")))"]).sendlocal(8000)
while 1:
send_weave_structure(driver.read_all())
time.sleep(1)
import pygame
import driver
import time
# standard lsystem stuff
def run_rule(str,rule):
if rule[1]=="": return str
ret = ""
for i in range(0,len(str)):
if str[i]==rule[0]:
ret+=rule[1]
else:
ret+=str[i]
return ret
def explode_lsystem(str,rules,gen):
for g in range(0, gen):
for r in rules:
str = run_rule(str,r)
return str
# a weave structure kernel
class kernel:
def __init__(self,structure,w,h):
self.structure = structure
self.width = w
self.height = h
# return warp or weft, dependant on the position
def stitch(self, x, y, warp, weft):
#if x % 2 == y % 2:
if self.structure[x%self.width+(y%self.height)*self.width]==1:
return warp
else:
return weft
def conv_colour(c):
if c=="R": return [255,50,100]
if c=="r": return [255,50,100]
if c=="B": return [50,200,255]
return [50,200,255]
pygame.init()
screen = pygame.display.set_mode([1024,768])
thr_warp_thin1 = pygame.image.load("thr-warp-thin.png")
thr_warp_thin1.set_palette_at(1,conv_colour("B"))
thr_warp_fat1 = pygame.image.load("thr-warp-fat.png")
thr_warp_fat1.set_palette_at(1,conv_colour("B"))
thr_weft_thin1 = pygame.image.load("thr-weft-thin.png")
thr_weft_thin1.set_palette_at(1,conv_colour("B"))
thr_weft_fat1 = pygame.image.load("thr-weft-fat.png")
thr_weft_fat1.set_palette_at(1,conv_colour("B"))
thr_warp_thin2 = pygame.image.load("thr-warp-thin.png")
thr_warp_thin2.set_palette_at(1,conv_colour("R"))
thr_warp_fat2 = pygame.image.load("thr-warp-fat.png")
thr_warp_fat2.set_palette_at(1,conv_colour("R"))
thr_weft_thin2 = pygame.image.load("thr-weft-thin.png")
thr_weft_thin2.set_palette_at(1,conv_colour("R"))
thr_weft_fat2 = pygame.image.load("thr-weft-fat.png")
thr_weft_fat2.set_palette_at(1,conv_colour("R"))
rect = thr_warp_thin1.get_rect()
#rectv.left=20
fat_red = 1
thin_red = 2
fat_blue = 4
thin_blue = 8
symbol_x = 3
symbol_y = 5
symbol_z = 9
def lsys_from_code(c):
if c==fat_red: return "R"
if c==fat_blue: return "B"
if c==thin_red: return "r"
if c==thin_blue: return "b"
if c==symbol_x: return "X"
if c==symbol_y: return "Y"
if c==symbol_z: return "Z"
return ""
def rule_from_code(sym,code):
t = ""
for i in range(0,8):
t+=lsys_from_code(code[i])
return [sym,t]
def remove_symbols(str):
ret=""
for i in range(0,len(str)):
if str[i]!="X" and str[i]!="Y" and str[i]!="Z":
ret+=str[i]
return ret
def lsys_from_blocks(code):
#axiom
axiom = ""
for i in range(0,8):
axiom+=lsys_from_code(code[i])
rule1=rule_from_code("X",code[8:16])
rule2=rule_from_code("Y",code[16:24])
rule3=rule_from_code("Z",code[24:32])
print("------")
print(axiom)
print(rule1)
print(rule2)
print(rule3)
return remove_symbols(explode_lsystem(axiom,[rule1,rule2,rule3],6))
def sprite_from_yarn(c,warp):
if warp:
if c=="B": return thr_warp_fat1
if c=="R": return thr_warp_fat2
if c=="r": return thr_warp_thin2
if c=="b": return thr_warp_thin1
return thr_warp_fat2
else:
if c=="B": return thr_weft_fat1
if c=="R": return thr_weft_fat2
if c=="r": return thr_weft_thin2
if c=="b": return thr_weft_thin1
return thr_weft_fat2
cell_spacing = 15
weave_width = 60
weave_height = 40
def draw_weave(time,kernel,warp_yarn,weft_yarn):
if warp_yarn=="" or weft_yarn=="": return
for y in range(0,weave_height):
rect.top=y*cell_spacing
for x in range(0,weave_width):
warp_over = kernel.stitch(x,y,True,False)
rect.left=x*cell_spacing
warp_sprite = sprite_from_yarn(warp_yarn[x%len(warp_yarn)],True)
weft_sprite = sprite_from_yarn(weft_yarn[y%len(weft_yarn)],False)
# draw order depends on weave
if warp_over:
if time>y:
screen.blit(weft_sprite, rect)
screen.blit(warp_sprite, rect)
else:
screen.blit(warp_sprite, rect)
if time>y:
screen.blit(weft_sprite, rect)
emu = [2,0,0,0,0,0,0,0,
2,0,0,0,0,0,0,0,
0,0,8,2,0,0,0,0,
0,0,0,0,0,0,0,0]
frame = 0
k = kernel([0,0,1,1,
0,1,1,0,
1,1,0,0,
1,0,0,1],4,4)
print("initing")
driver.init()
print(driver.read_all())
while 1:
yarn = lsys_from_blocks(driver.read_all())
#yarn = lsys_from_blocks(emu)
print(yarn)
screen.fill([0,0,0])
draw_weave(frame,k,yarn,yarn)
pygame.display.flip()
frame += 1
if frame>weave_width: frame=0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; weavecoding raspberry pi installation
(rotate (vector 0 -45 0))
(define weft (build-jellyfish 4096))
(define warp (build-jellyfish 4096))
(define weave-scale (vector 0.2 -0.2 0.2))
(with-primitive
weft
(program-jelly
30 prim-triangles
'(let ((vertex positions-start)
(t 0)
(v 0)
(weft-direction (vector 2 0 0))
(weft-position (vector -20 0 0))
(weft-t 0)
(draft-pos 0)
(draft-size 4)
(draft 1) (d-b 0) (d-c 1) (d-d 0)
(d-e 0) (d-f 1) (d-g 0) (d-h 1)
(d-i 1) (d-j 0) (d-k 1) (d-l 0)
(d-m 0) (d-n 1) (d-o 0) (d-p 1)
(weft-z (vector 0 0 0))
(weft-count 0)
(weft-total 21))
(trace (addr draft))
(define read-draft
(lambda ()
(read
(+ (addr draft)
(+ (* draft-pos draft-size)
(if (> weft-direction 0)
(modulo weft-count (+ draft-size (vector 0 1 1)) )
(modulo (- (- weft-total 1) weft-count) (+ draft-size (vector 0 1 1)) )))))))
(define calc-weft-z
(lambda ()
(set! weft-count (+ weft-count 1))
(set! weft-z
(if (> (read-draft) 0.5)
(vector 0 0 0.01)
(vector 0 0 -0.01)))))
(define right-selvedge
(lambda (gap)
;; top corner
(write! vertex
(- (+ weft-position (vector 2 0 0)) gap)
(- (+ weft-position (vector 3 1 0)) gap)
(- (+ weft-position (vector 2 1 0)) gap))
(set! vertex (+ vertex 3))
;; vertical connection
(write! vertex
(- (+ weft-position (vector 3 1 0)) gap)
(- (+ weft-position (vector 2 1 0)) gap)
(+ weft-position (vector 2 0 0))
(- (+ weft-position (vector 3 1 0)) gap)
(+ weft-position (vector 2 0 0))
(+ weft-position (vector 3 0 0)))
(set! vertex (+ vertex 6))
;; bottom corner
(write! vertex
(+ weft-position (vector 2 0 0))
(+ weft-position (vector 3 0 0))
(+ weft-position (vector 2 1 0)))
(set! vertex (+ vertex 3))
))
(define left-selvedge
(lambda (gap)
;; top corner
(write! vertex
(- (+ weft-position (vector 0 0 0)) gap)
(- (+ weft-position (vector -1 1 0)) gap)
(- (+ weft-position (vector 0 1 0)) gap))
(set! vertex (+ vertex 3))
;; vertical connection
(write! vertex
(- (+ weft-position (vector -1 1 0)) gap)
(- (+ weft-position (vector 0 1 0)) gap)
(+ weft-position (vector 0 0 0))
(- (+ weft-position (vector -1 1 0)) gap)
(+ weft-position (vector 0 0 0))
(+ weft-position (vector -1 0 0)))
(set! vertex (+ vertex 6))
;; bottom corner
(write! vertex
(+ weft-position (vector 0 0 0))
(+ weft-position (vector -1 0 0))
(+ weft-position (vector 0 1 0)))
(set! vertex (+ vertex 3))
))