summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgreenarrow <greenarrow>2008-05-01 14:00:08 +0000
committergreenarrow <greenarrow@cb376a5e-1013-0410-a455-b6b1f9ac8223>2008-05-01 14:00:08 +0000
commit08f6c78aa131db359a0cc9619812480de6786da0 (patch)
tree8b3c50dc54529c422a45ac770f64dbf21eaf2140
parentbc2a485cd3c51187c49302a0d96d815f2137ac56 (diff)
downloadreprap-08f6c78aa131db359a0cc9619812480de6786da0.tar.gz
reprap-08f6c78aa131db359a0cc9619812480de6786da0.zip
Added pen calibration tool, lots of bugs fixed, incorperated dxf plotting to gui program
git-svn-id: https://reprap.svn.sourceforge.net/svnroot/reprap@1551 cb376a5e-1013-0410-a455-b6b1f9ac8223
-rw-r--r--trunk/users/stef/pyRepRap/README70
-rw-r--r--trunk/users/stef/pyRepRap/dist/pyRepRap-0.3.tar.gzbin30487 -> 79216 bytes
-rw-r--r--trunk/users/stef/pyRepRap/examples/demo.py31
-rw-r--r--trunk/users/stef/pyRepRap/reprap/reprap.py65
-rw-r--r--trunk/users/stef/pyRepRap/reprap/wxpygame.py6
-rw-r--r--trunk/users/stef/pyRepRap/scripts/reprapcontrol313
-rwxr-xr-xtrunk/users/stef/pyRepRap/scripts/reprapplot1123
-rw-r--r--trunk/users/stef/pyRepRap/setup.py5
8 files changed, 1417 insertions, 196 deletions
diff --git a/trunk/users/stef/pyRepRap/README b/trunk/users/stef/pyRepRap/README
index 7ca553b8..ce4ac5c1 100644
--- a/trunk/users/stef/pyRepRap/README
+++ b/trunk/users/stef/pyRepRap/README
@@ -1,7 +1,18 @@
pyRepRap
+
Requirements:
-pyserial
+pyserial (for all)
+pymedia (for rrplotdxf & reprapplot)
+wxpython (for reprapplot)
+
+To install dependencies under Fedora / Redhat run:
+sudo yum install pyserial pymedia wxpython
+
+To install dependencies under Ubuntu run:
+sudo apt-get install pyserial pymedia wxpython
+
+
How to Install :
python setup.py build
@@ -15,22 +26,55 @@ What's included:
scripts:
reprapcontrol Handy command line control program for RepRap
rrplotdxf Plot dxf CAD files on RepRap
- rrplotgerber Plot gerber PCB files on RepRap
+ reprapplot Plot gerber PCB files on RepRap (Graphical)
+
+
Once the package is installed you can run the scripts from the command line at any time
+Scritps require serial port permissions. Either run as root or change serial permissions:
+ (as root)
+ chown yourusername /dev/ttyS0
+ chmod 0600 /dev/ttyS0
+ (see http://gphoto.sourceforge.net/doc/manual/permissions-serial.html)
+
+
+reprapplot Howto:
+1) run reprapplot
+2) click 'open', select gerber file
+3) click plot to view a preview of the plot (move with mouse drag and zoom with wheel)
+4) adjust preferences and click plot again to tweak as required
+5) Cick 'enable repap'
+6) Click 'reset' (wait)
+7) Click 'pen setup', click down until pen is making good contact with paper
+8) click pen up test and pen down test to make sure good pen movement is achieved
+9) remember the down position value and enter it in preferences (TODO).
+10) Click plot
+
+
+Known issues:
+Preferences do not save
+
+
+
+
-Licence :
-pyRepRap is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-pyRepRap is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+Licenced under GNU v2 and the 'I'm not going to help you kill people licence'. The latter overrules the former.
+
+I'm not going to help you kill people licence v1:
+The use of this software in any form for any purposes relating to any form of military activity or
+research either directly or via subcontracts is strictly prohibited.
+Any company or organisation affiliated with any military organisations either directly or through
+subcontracts are strictly prohibited from using any part of this software.
-You should have received a copy of the GNU General Public License
-along with pyRepRap. If not, see <http://www.gnu.org/licenses/>.
+GNU licence:
+RepRap Gerber Plotter is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free Software Foundation;
+either version 2 of the License, or (at your option) any later version.
+RepRap Gerber Plotter is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See the GNU General Public License for more details. You should have received a copy of
+the GNU General Public License along with File Hunter; if not, write to
+the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
diff --git a/trunk/users/stef/pyRepRap/dist/pyRepRap-0.3.tar.gz b/trunk/users/stef/pyRepRap/dist/pyRepRap-0.3.tar.gz
index 305b6a49..170683c7 100644
--- a/trunk/users/stef/pyRepRap/dist/pyRepRap-0.3.tar.gz
+++ b/trunk/users/stef/pyRepRap/dist/pyRepRap-0.3.tar.gz
Binary files differ
diff --git a/trunk/users/stef/pyRepRap/examples/demo.py b/trunk/users/stef/pyRepRap/examples/demo.py
index 6cfba42f..00c68369 100644
--- a/trunk/users/stef/pyRepRap/examples/demo.py
+++ b/trunk/users/stef/pyRepRap/examples/demo.py
@@ -1,18 +1,29 @@
import serial, reprap, time # Import the reprap and pySerial modules.
-reprap.serial = serial.Serial(0, 19200, timeout = reprap.snap.messageTimeout) # Initialise serial port, here the first port (0) is used.
-reprap.cartesian.x.active = True # These devices are present in network, will automatically scan in the future.
+
+reprap.openSerial( 0, 19200, 60 ) # Initialise serial port, here the first port (0) is used.
+
+reprap.cartesian.x.active = True # These devices are present in network, will automatically scan in the future.
reprap.cartesian.y.active = True
reprap.cartesian.z.active = True
reprap.extruder.active = True
+
+reprap.cartesian.x.setNotify() # Set x axis to notify arrivals
+reprap.cartesian.y.setNotify() # Set y axis to notify arrivals
+reprap.cartesian.z.setNotify() # Set z axis to notify arrivals
+
+reprap.cartesian.setMoveSpeed(220) # Set stepper speed to 220 (out of 255)
+reprap.cartesian.setPower( int( 83 * 0.63 ) ) # Set power to 83%
+
# The module is now ready to recieve commands #
-moveSpeed = 220
-reprap.cartesian.homeReset( moveSpeed, True ) # Send all axies to home position. Wait until arrival.
-reprap.cartesian.seek( (1000, 1000, 0), moveSpeed, True ) # Seek to (1000, 1000, 0). Wait until arrival.
-time.sleep(2) # Pause.
-reprap.cartesian.seek( (500, 1000, 0), moveSpeed, True ) # Seek to (500, 1000, 0). Wait until arrival.
+
+reprap.cartesian.homeReset() # Send all axies to home position. Wait until arrival.
+reprap.cartesian.seek( (1000, 1000, 0) ) # Seek to (1000, 1000, 0). Wait until arrival.
+time.sleep(2) # Pause.
+reprap.cartesian.seek( (500, 1000, 0) ) # Seek to (500, 1000, 0). Wait until arrival.
time.sleep(2)
-reprap.cartesian.seek( (1000, 500, 0), moveSpeed, True ) # Seek to (1000, 500, 0). Wait until arrival.
+reprap.cartesian.seek( (1000, 500, 0) ) # Seek to (1000, 500, 0). Wait until arrival.
time.sleep(2)
-reprap.cartesian.seek( (100, 100, 0), moveSpeed, True ) # Seek to (100, 100, 0). Wait until arrival.
-reprap.cartesian.homeReset( moveSpeed, True ) # Send all axies to home position. Wait until arrival.
+reprap.cartesian.seek( (100, 100, 0) ) # Seek to (100, 100, 0). Wait until arrival.
+
+reprap.cartesian.homeReset() # Send all axies to home position. Wait until arrival.
reprap.cartesian.free() # Shut off power to all motors.
diff --git a/trunk/users/stef/pyRepRap/reprap/reprap.py b/trunk/users/stef/pyRepRap/reprap/reprap.py
index 1dea7b18..b7ee104f 100644
--- a/trunk/users/stef/pyRepRap/reprap/reprap.py
+++ b/trunk/users/stef/pyRepRap/reprap/reprap.py
@@ -72,11 +72,9 @@ sync_inc = 2 # inc motor on each pulse
sync_dec = 3 # dec motor on each pulse
snap.localAddress = 0 # local address of host PC. This will always be 0.
-#global serialPort
-#serialPort = False
defaultSpeed = 220
-moveSpeed = 221
+#moveSpeed = 221
def openSerial( port = 0, rate = 19200, tout = 60 ):
global serialPort
@@ -163,7 +161,7 @@ class extruderClass:
return data[1], data[2]
return False
- def setMotor(self, direction, speed = moveSpeed):
+ def setMotor(self, direction, speed):
if self.active:
p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [int(direction), int(speed)] ) ##no command being sent, whats going on?
if p.send():
@@ -227,6 +225,7 @@ class axisClass:
self.active = False # when scanning network, set this, then in each func below, check alive before doing anything
self.limit = 100000 # limit effectively disabled unless set
#self.turnArroundSteps = False
+ self.speed = defaultSpeed
#move axis one step forward
def forward1(self):
if self.active:
@@ -244,16 +243,20 @@ class axisClass:
return False
#spin axis forward at given speed
- def forward(self, speed = moveSpeed):
- if self.active:
+ def forward(self, speed = False):
+ if not speed:
+ speed = self.speed
+ if self.active and speed >=0 and speed <=255:
p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_FORWARD, int(speed)] )
if p.send():
return True
return False
#spin axis backward at given speed
- def backward(self, speed = moveSpeed):
- if self.active:
+ def backward(self, speed = False):
+ if not speed: # If speed is not specified use stored (or default)
+ speed = self.speed
+ if self.active and speed >=0 and speed <=255:
p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_REVERSE, int(speed)] )
if p.send():
return True
@@ -284,7 +287,7 @@ class axisClass:
#set current position (set variable not robot position)
def setPos(self, pos):
- if self.active:
+ if self.active and pos >=0 and pos <= 0xFFFF:
posMSB ,posLSB = int2bytes( pos )
p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_SETPOS, posMSB, posLSB] )
if p.send():
@@ -300,8 +303,10 @@ class axisClass:
return False
#seek to axis location. When waitArrival is True, funtion does not return until seek is compete
- def seek(self, pos, speed = moveSpeed, waitArrival = True):
- if self.active and pos <= self.limit:
+ def seek(self, pos, speed = False, waitArrival = True):
+ if not speed:
+ speed = self.speed
+ if self.active and pos <= self.limit and pos >=0 and pos <= 0xFFFF and speed >=0 and speed <=255:
posMSB ,posLSB = int2bytes( pos )
p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_SEEK, int(speed), posMSB ,posLSB] )
if p.send():
@@ -317,8 +322,10 @@ class axisClass:
return False
#goto 0 position. When waitArrival is True, funtion does not return until reset is compete
- def homeReset(self, speed = moveSpeed, waitArrival = True):
- if self.active:
+ def homeReset(self, speed = False, waitArrival = True):
+ if not speed:
+ speed = self.speed
+ if self.active and speed >=0 and speed <=255:
p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_HOMERESET, int(speed)] )
if p.send():
if waitArrival:
@@ -341,14 +348,16 @@ class axisClass:
return False
def setSync( self, syncMode ):
- if self.active:
+ if self.active and syncMode >=0 and syncMode <=255:
p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_SYNC, int(syncMode)] )
if p.send():
return True
return False
- def DDA( self, speed, seekTo, slaveDelta, waitArrival = True):
- if self.active and seekTo <= self.limit:
+ def DDA( self, seekTo, slaveDelta, speed = False, waitArrival = True):
+ if not speed:
+ speed = self.speed
+ if self.active and seekTo <= self.limit and seekTo >=0 and seekTo <= 0xFFFF and slaveDelta >=0 and slaveDelta <= 0xFFFF and speed >=0 and speed <=255:
masterPosMSB, masterPosLSB = int2bytes( seekTo )
slaveDeltaMSB, slaveDeltaLSB = int2bytes( slaveDelta )
p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_DDA, int(speed), masterPosMSB ,masterPosLSB, slaveDeltaMSB, slaveDeltaLSB] ) #start sync
@@ -363,14 +372,14 @@ class axisClass:
return False
def setPower( self, power ):
- if self.active:
+ if self.active and power >=0 and power <=63:
p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_SETPOWER, int( power * 0.63 )] ) # This is a value from 0 to 63 (6 bits)
if p.send():
return True
return False
def setMoveSpeed(self, speed):
- self.moveSpeed = speed
+ self.speed = speed
#def setTurnaroundSteps(self, steps):
# self.turnArroundSteps = steps
@@ -398,18 +407,22 @@ class cartesianClass:
self.z = axisClass(4)
# goto home position (all axies)
- def homeReset(self, speed = moveSpeed, waitArrival = True):
+ def homeReset(self, speed = False, waitArrival = True):
+ #z is done first so we don't break anything we just made
+ if self.z.homeReset( speed = speed, waitArrival = waitArrival ):
+ print "Z Reset"
if self.x.homeReset( speed = speed, waitArrival = waitArrival ): #setting these to true breaks waitArrival convention. need to rework waitArrival and possibly have each axis storing it's arrival flag and pos as variables?
print "X Reset"
if self.y.homeReset( speed = speed, waitArrival = waitArrival ):
print "Y Reset"
- if self.z.homeReset( speed = speed, waitArrival = waitArrival ):
- print "Z Reset"
+
# add a way to collect all three notifications (in whatever order) then check they are all there. this will allow symultanious axis movement and use of waitArrival
# seek to location (all axies). When waitArrival is True, funtion does not return until all seeks are compete
# seek will automatically use syncSeek when it is required. Always use the seek function
- def seek(self, pos, speed = moveSpeed, waitArrival = True):
+ def seek(self, pos, speed = False, waitArrival = True):
+ if not speed:
+ speed = self.speed
curX, curY, curZ = self.x.getPos(), self.y.getPos(), self.z.getPos()
x, y, z = pos
if x <= self.x.limit and y <= self.y.limit and z <= self.z.limit:
@@ -429,7 +442,9 @@ class cartesianClass:
print "Trying to print outside of limit, aborting seek"
# perform syncronised x/y movement. This is called by seek when needed.
- def syncSeek(self, pos, speed = moveSpeed, waitArrival = True):
+ def syncSeek(self, pos, speed = False, waitArrival = True):
+ if not speed:
+ speed = self.speed
curX, curY = self.x.getPos(), self.y.getPos()
newX, newY, nullZ = pos
deltaX = abs( curX - newX ) # calc delta movements
@@ -447,7 +462,7 @@ class cartesianClass:
if printDebug: print " switching to y master"
if printDebug: print " masterPos", master.seekTo, "slaveDelta", slave.delta
slave.axis.setSync( slave.syncMode )
- master.axis.DDA( speed, master.seekTo, slave.delta, True )
+ master.axis.DDA( master.seekTo, slave.delta, speed, True )
time.sleep(0.1)
slave.axis.setSync( sync_none )
if printDebug: print " sync seek complete"
@@ -474,7 +489,7 @@ class cartesianClass:
#def lockout():
#keep sending power down commands to all board every second
def setMoveSpeed(self, speed):
- self.moveSpeed = speed
+ self.speed = speed
self.x.setMoveSpeed(speed)
self.y.setMoveSpeed(speed)
self.z.setMoveSpeed(speed)
diff --git a/trunk/users/stef/pyRepRap/reprap/wxpygame.py b/trunk/users/stef/pyRepRap/reprap/wxpygame.py
index 8a3f9b4f..3f3d04e9 100644
--- a/trunk/users/stef/pyRepRap/reprap/wxpygame.py
+++ b/trunk/users/stef/pyRepRap/reprap/wxpygame.py
@@ -1,5 +1,5 @@
"""
-Code derived from a combination of :
+Code derived from a vague combination of :
BufferedCanvas -- Double-buffered, flicker-free canvas widget
Copyright (C) 2005, 2006 Daniel Keep
@@ -104,6 +104,10 @@ class wxSDLPanel(wx.Panel):
def getSurface(self):
return self._surface
+ def update(self):
+ self.Refresh()
+ print "r"
+
def MouseMove(self, event):
raise NotImplementedError('please define a .MouseMove() method!')
def OnMouseDown(self, event):
diff --git a/trunk/users/stef/pyRepRap/scripts/reprapcontrol b/trunk/users/stef/pyRepRap/scripts/reprapcontrol
index 8aa02b7b..d714a2b8 100644
--- a/trunk/users/stef/pyRepRap/scripts/reprapcontrol
+++ b/trunk/users/stef/pyRepRap/scripts/reprapcontrol
@@ -6,152 +6,173 @@ import serial, reprap, time, sys
#reprap.snap.printFailedPackets = True
#reprap.printDebug = True
-reprap.openSerial( 0, 19200, 60 )
-#print reprap.serialPort
-
-reprap.cartesian.x.active = True # these devices are present in network
-reprap.cartesian.y.active = True
-reprap.cartesian.z.active = True
-reprap.extruder.active = True
-
-reprap.cartesian.x.setNotify()
-reprap.cartesian.y.setNotify()
-reprap.cartesian.z.setNotify()
-reprap.cartesian.x.limit = 2523
-#reprap.cartesian.y.limit = 2743
-reprap.cartesian.y.limit = 2000
-#work surface approx x 2523, y 2743
-
-def printHelp():
- print "\nreprapcontrol command [args]"
- print " Commands:"
- print " stop Stop all axies"
- print " reset Send all axies to home"
- print " pos Print current position"
- print " goto [x] [y] Go to specified position"
- print " power [0 to 63] Set power level"
- print " go Test routine"
- print " free Power off steper motors"
- print " run [x/y] [speed] Spin motor forwards"
- print " runb [x/y] [speed] Spin motor backwards"
- print " step [x/y] Step motor forward"
-
-def printPos():
- x, y, z = reprap.cartesian.getPos()
- print "Location [" + str(x) + ", " + str(y) + ", " + str(z) + "]"
-
-
-print "================================================================"
-
-
-if len(sys.argv) < 2:
- printHelp()
+if reprap.openSerial( 0, 19200, 60 ):
+
+ #print reprap.serialPort
+
+ reprap.cartesian.x.active = True # these devices are present in network
+ reprap.cartesian.y.active = True
+ reprap.cartesian.z.active = True
+ reprap.extruder.active = True
+
+ reprap.cartesian.x.setNotify()
+ reprap.cartesian.y.setNotify()
+ reprap.cartesian.z.setNotify()
+ reprap.cartesian.x.limit = 2523
+ #reprap.cartesian.y.limit = 2743
+ reprap.cartesian.y.limit = 2000
+ #work surface approx x 2523, y 2743
+
+ def printHelp():
+ print "\nreprapcontrol command [args]"
+ print " Commands:"
+ print " stop Stop all axies"
+ print " reset Send all axies to home"
+ print " pos Print current position"
+ print " goto [x] [y] Go to specified position"
+ print " power [0 to 63] Set power level"
+ print " speed [0 to 255] Set steper speed"
+ print " go Test routine"
+ print " free Power off steper motors"
+ print " run [x/y] [speed] Spin motor forwards"
+ print " runb [x/y] [speed] Spin motor backwards"
+ print " step [x/y/z] Step motor forward"
+ print " stepb [x/y/z] Step motor backwards"
+
+ def printPos():
+ x, y, z = reprap.cartesian.getPos()
+ print "Location [" + str(x) + ", " + str(y) + ", " + str(z) + "]"
+
+
+ print "================================================================"
+
+
+ if len(sys.argv) < 2:
+ printHelp()
-########### control of cartesian frame as a whole #########
-
-#stop all steppers
-if sys.argv[1] == "stop":
- reprap.cartesian.stop()
-
-#goto 0,0
-elif sys.argv[1] == "reset":
- reprap.cartesian.homeReset( 200, True )
- #time.sleep(2)
- printPos()
-
-#print current positon
-elif sys.argv[1] == "pos":
- printPos()
-
-#goto a specific location
-elif sys.argv[1] == "goto":
- reprap.cartesian.seek( ( int(sys.argv[2]), int(sys.argv[3]), 0 ), 200, False)
- printPos()
-
-#goto a specific location (use sync)
-elif sys.argv[1] == "gotos":
- reprap.cartesian.syncSeek( ( int(sys.argv[2]), int(sys.argv[3]), 0 ), 200, False)
- printPos()
-
-elif sys.argv[1] == "power":
- reprap.cartesian.setPower( int( sys.argv[2] ) ) # This is a value from 0 to 63 (6 bits)
-
-
-#test routine
-elif sys.argv[1] == "go": #stepper test
- reprap.cartesian.seek( (1000, 1000, 0), 200, True )
- time.sleep(2)
- reprap.cartesian.seek( (500, 1000, 0), 200, True )
- time.sleep(2)
- reprap.cartesian.seek( (500, 500, 0), 200, True )
- time.sleep(2)
- reprap.cartesian.seek( (10, 10, 0), 200, True )
-
-#free motors (switch off all coils)
-elif sys.argv[1] == "free":
- reprap.cartesian.free()
-
-############## control of individual steppers #############
-
-#spin stepper
-elif sys.argv[1] == "run": # run axis
- if sys.argv[2] == "x":
- reprap.cartesian.x.forward( int(sys.argv[3]) )
- elif sys.argv[2] == "y":
- reprap.cartesian.y.forward( int(sys.argv[3]) )
-
-#spin stepper in reverse
-elif sys.argv[1] == "runb": #runb axis
- if sys.argv[2] == "x":
- reprap.axies.backward( reprap.axisX, int(sys.argv[3]) )
- elif sys.argv[2] == "y":
- reprap.axies.backward( reprap.axisY, int(sys.argv[3]) )
-
-elif sys.argv[1] == "step":
- if sys.argv[2] == "x":
- reprap.cartesian.x.forward1()
- elif sys.argv[2] == "y":
- reprap.cartesian.y.forward1()
-
-################# control of extruder #####################
-
-#test extrder motor
-elif sys.argv[1] == "motor":
- nn = 0
- while 1:
- if nn > 0:
- nn = 0
- else:
- nn = 150
- reprap.extruder.setMotor(reprap.CMD_REVERSE, nn)
- time.sleep(1)
-
-elif sys.argv[1] == "getinfo":
- mtype = reprap.extruder.getModuleType()
- version = reprap.extruder.getVersion()
- print "module", mtype, "version", version
-
-elif sys.argv[1] == "heat":
- reprap.extruder.setHeat(255, 255, 255, 255)
-
-#setHeat(self, lowHeat, highHeat, tempTarget, tempMax
-
-elif sys.argv[1] == "temp":
- print "Temp is ", reprap.extruder.getTemp()
-
-elif sys.argv[1] == "setref":
- reprap.extruder.setVoltateReference( int(sys.argv[2]) )
-
-
-
-
-############### scan network for devices ###################
-
-#scan snap network
-elif sys.argv[1] == "scan":
- reprap.scanNetwork()
-
-else:
- printHelp()
+ ########### control of cartesian frame as a whole #########
+
+ #stop all steppers
+ if sys.argv[1] == "stop":
+ reprap.cartesian.stop()
+
+ #goto 0,0
+ elif sys.argv[1] == "reset":
+ reprap.cartesian.homeReset( waitArrival = False )
+ #time.sleep(2)
+ printPos()
+
+ #print current positon
+ elif sys.argv[1] == "pos":
+ printPos()
+
+ #goto a specific location
+ elif sys.argv[1] == "goto":
+ #reprap.cartesian.seek( ( int(sys.argv[2]), int(sys.argv[3]), 0 ), waitArrival = False)
+ reprap.cartesian.seek( ( int(sys.argv[2]), int(sys.argv[3]), int(sys.argv[4]) ), waitArrival = False)
+ printPos()
+
+ #goto a specific location (use sync)
+ elif sys.argv[1] == "gotos":
+ reprap.cartesian.syncSeek( ( int(sys.argv[2]), int(sys.argv[3]), 0 ), waitArrival = False)
+ printPos()
+
+ elif sys.argv[1] == "power":
+ reprap.cartesian.setPower( int( sys.argv[2] ) ) # This is a value from 0 to 63 (6 bits)
+
+ elif sys.argv[1] == "speed":
+ reprap.cartesian.setMoveSpeed( int( sys.argv[2] ) ) # This is a value from 0 to 255
+
+
+ #test routine
+ elif sys.argv[1] == "go": #stepper test
+ reprap.cartesian.seek( (1000, 1000, 0), 200, True )
+ time.sleep(2)
+ reprap.cartesian.seek( (500, 1000, 0), 200, True )
+ time.sleep(2)
+ reprap.cartesian.seek( (500, 500, 0), 200, True )
+ time.sleep(2)
+ reprap.cartesian.seek( (10, 10, 0), 200, True )
+
+ #free motors (switch off all coils)
+ elif sys.argv[1] == "free":
+ reprap.cartesian.free()
+
+ ############## control of individual steppers #############
+
+ #spin stepper
+ elif sys.argv[1] == "run": # run axis
+ if sys.argv[2] == "x":
+ reprap.cartesian.x.forward( int(sys.argv[3]) )
+ elif sys.argv[2] == "y":
+ reprap.cartesian.y.forward( int(sys.argv[3]) )
+ elif sys.argv[2] == "z":
+ reprap.cartesian.z.forward( int(sys.argv[3]) )
+
+ #spin stepper in reverse
+ elif sys.argv[1] == "runb": #runb axis
+ if sys.argv[2] == "x":
+ reprap.cartesian.x.backward( int(sys.argv[3]) )
+ elif sys.argv[2] == "y":
+ reprap.cartesian.y.backward( int(sys.argv[3]) )
+ elif sys.argv[2] == "z":
+ reprap.cartesian.z.backward( int(sys.argv[3]) )
+
+ elif sys.argv[1] == "step":
+ if sys.argv[2] == "x":
+ reprap.cartesian.x.forward1()
+ elif sys.argv[2] == "y":
+ reprap.cartesian.y.forward1()
+ elif sys.argv[2] == "z":
+ reprap.cartesian.z.forward1()
+
+ elif sys.argv[1] == "stepb":
+ if sys.argv[2] == "x":
+ reprap.cartesian.x.backward1()
+ elif sys.argv[2] == "y":
+ reprap.cartesian.y.backward1()
+ elif sys.argv[2] == "z":
+ reprap.cartesian.z.backward1()
+
+ ################# control of extruder #####################
+
+ #test extrder motor
+ elif sys.argv[1] == "motor":
+ nn = 0
+ while 1:
+ if nn > 0:
+ nn = 0
+ else:
+ nn = 150
+ reprap.extruder.setMotor(reprap.CMD_REVERSE, nn)
+ time.sleep(1)
+
+ elif sys.argv[1] == "getinfo":
+ mtype = reprap.extruder.getModuleType()
+ version = reprap.extruder.getVersion()
+ print "module", mtype, "version", version
+
+ elif sys.argv[1] == "heat":
+ reprap.extruder.setHeat(255, 255, 255, 255)
+
+ #setHeat(self, lowHeat, highHeat, tempTarget, tempMax
+
+ elif sys.argv[1] == "temp":
+ print "Temp is ", reprap.extruder.getTemp()
+
+ elif sys.argv[1] == "setref":
+ reprap.extruder.setVoltateReference( int(sys.argv[2]) )
+
+
+
+
+ ############### scan network for devices ###################
+
+ #scan snap network
+ elif sys.argv[1] == "scan":
+ reprap.scanNetwork()
+
+ else:
+ printHelp()
diff --git a/trunk/users/stef/pyRepRap/scripts/reprapplot b/trunk/users/stef/pyRepRap/scripts/reprapplot
new file mode 100755
index 00000000..cb86b796
--- /dev/null
+++ b/trunk/users/stef/pyRepRap/scripts/reprapplot
@@ -0,0 +1,1123 @@
+#!/usr/bin/env python
+"""
+Licenced under GNU v2 and the 'I'm not going to help you kill people licence'. The latter overrules the former.
+
+I'm not going to help you kill people licence v1:
+The use of this software in any form for any purposes relating to any form of military activity or
+research either directly or via subcontracts is strictly prohibited.
+Any company or organisation affiliated with any military organisations either directly or through
+subcontracts are strictly prohibited from using any part of this software.
+
+GNU licence:
+RepRap Plotter is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free Software Foundation;
+either version 2 of the License, or (at your option) any later version.
+
+RepRap Plotter is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See the GNU General Public License for more details. You should have received a copy of
+the GNU General Public License along with File Hunter; if not, write to
+the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+# -*- coding: utf-8 -*-
+# generated by wxGlade 0.6.1 on Wed Apr 23 11:49:08 2008
+
+import wx, pygame, reprap, time, sys, os, wx.wizard
+import reprap.wxpygame as wxpygame
+import reprap.gerberplot as gerberplot
+import reprap.dxfplot as dxfplot
+
+#iconPath = reprap.__path__[0] + "/graphics/"
+iconPath = "/usr/share/reprap/icons/"
+
+# begin wxGlade: extracode
+# end wxGlade
+
+# Class to store preferences
+class Wizard_Page1(wx.Panel):
+ def __init__(self, *args, **kwds):
+ # begin wxGlade: Wizard_Page1.__init__
+ kwds["style"] = wx.TAB_TRAVERSAL
+ wx.Panel.__init__(self, *args, **kwds)
+ self.sizer_1_staticbox = wx.StaticBox(self, -1, "Reset")
+ self.label_15 = wx.StaticText(self, -1, "This wizard is designed to assist with pen alignment.\n\nPress the 'Reset' button to reset the Z axis to 0.\n")
+ self.button_Reset = wx.Button(self, -1, "Reset")
+
+ self.__set_properties()
+ self.__do_layout()
+
+ self.Bind(wx.EVT_BUTTON, self.hanBtnReset, self.button_Reset)
+ # end wxGlade
+
+ def __set_properties(self):
+ # begin wxGlade: Wizard_Page1.__set_properties
+ pass
+ # end wxGlade
+
+ def __do_layout(self):
+ # begin wxGlade: Wizard_Page1.__do_layout
+ sizer_1 = wx.StaticBoxSizer(self.sizer_1_staticbox, wx.VERTICAL)
+ sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
+ sizer_1.Add(self.label_15, 0, wx.ALL|wx.EXPAND|wx.ADJUST_MINSIZE, 12)
+ sizer_2.Add(self.button_Reset, 1, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0)
+ sizer_1.Add(sizer_2, 1, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 25)
+ self.SetSizer(sizer_1)
+ sizer_1.Fit(self)
+ # end wxGlade
+
+ def setNextPanel(self, panel):
+ self.nextPanel = panel
+
+ def hanBtnReset(self, event): # wxGlade: Wizard_Page1.<event_handler>
+ reprap.cartesian.z.homeReset()
+ self.pos = reprap.cartesian.z.getPos()
+ self.nextPanel.pos = self.pos
+ self.nextPanel.text_penUpPos.SetValue( str(self.nextPanel.pos) )
+# end of class Wizard_Page1
+
+
+class Wizard_Page2(wx.Panel):
+ def __init__(self, *args, **kwds):
+ # begin wxGlade: Wizard_Page2.__init__
+ kwds["style"] = wx.TAB_TRAVERSAL
+ wx.Panel.__init__(self, *args, **kwds)
+ self.sizer_27_staticbox = wx.StaticBox(self, -1, "Pen Position")
+ self.sizer_3_staticbox = wx.StaticBox(self, -1, "Pen Up Position")
+ self.sizer_24_copy_staticbox = wx.StaticBox(self, -1, "Move Pen")
+ self.label_20 = wx.StaticText(self, -1, "Use the 'Up' and 'Down' buttons, or enter a value manually to position the pen where it is just a few millimeters above the paper.")
+ self.button_stepUp_up = wx.Button(self, wx.ID_UP, "")
+ self.button_stepDown_up = wx.Button(self, wx.ID_DOWN, "")
+ self.text_penUpPos = wx.TextCtrl(self, -1, "0")
+ self.button_apply_up = wx.Button(self, wx.ID_APPLY, "")
+
+ self.__set_properties()
+ self.__do_layout()
+
+ self.Bind(wx.EVT_BUTTON, self.OnBtnStepUp, self.button_stepUp_up)
+ self.Bind(wx.EVT_BUTTON, self.OnBtnStepDown, self.button_stepDown_up)
+ self.Bind(wx.EVT_BUTTON, self.hanBtnApplyUp, self.button_apply_up)
+ # end wxGlade
+
+
+
+ def __set_properties(self):
+ # begin wxGlade: Wizard_Page2.__set_properties
+ pass
+ # end wxGlade
+
+ def __do_layout(self):
+ # begin wxGlade: Wizard_Page2.__do_layout
+ sizer_3 = wx.StaticBoxSizer(self.sizer_3_staticbox, wx.VERTICAL)
+ sizer_27 = wx.StaticBoxSizer(self.sizer_27_staticbox, wx.VERTICAL)
+ sizer_14_copy = wx.BoxSizer(wx.HORIZONTAL)
+ sizer_24_copy = wx.StaticBoxSizer(self.sizer_24_copy_staticbox, wx.VERTICAL)
+ sizer_3.Add(self.label_20, 0, wx.ALL|wx.EXPAND|wx.ADJUST_MINSIZE, 12)
+ sizer_24_copy.Add(self.button_stepUp_up, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0)
+ sizer_24_copy.Add(self.button_stepDown_up, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0)
+ sizer_3.Add(sizer_24_copy, 0, wx.ALL|wx.EXPAND, 6)
+ sizer_14_copy.Add(self.text_penUpPos, 1, wx.ADJUST_MINSIZE, 0)
+ sizer_14_copy.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_14_copy.Add(self.button_apply_up, 0, wx.ADJUST_MINSIZE, 0)
+ sizer_27.Add(sizer_14_copy, 1, wx.EXPAND, 0)
+ sizer_3.Add(sizer_27, 0, wx.ALL|wx.EXPAND, 6)
+ self.SetSizer(sizer_3)
+ sizer_3.Fit(self)
+ # end wxGlade
+
+ def setNextPanel(self, panel):
+ self.nextPanel = panel
+
+ def OnBtnStepUp(self, event): # wxGlade: Wizard_Page2.<event_handler>
+ self.pos = reprap.cartesian.z.getPos()
+ self.pos -= 1
+ reprap.cartesian.z.seek(self.pos)
+ self.text_penUpPos.SetValue( str(self.pos) )
+ self.nextPanel.pos = self.pos
+ self.nextPanel.text_penDownPos.SetValue( str(self.nextPanel.pos) )
+ self.nextPanel.nextPanel.downPos = self.pos
+
+
+ def OnBtnStepDown(self, event): # wxGlade: Wizard_Page2.<event_handler>
+ self.pos = reprap.cartesian.z.getPos()
+ self.pos += 1
+ reprap.cartesian.z.seek(self.pos)
+ self.text_penUpPos.SetValue( str(self.pos) )
+ self.nextPanel.pos = self.pos
+ self.nextPanel.text_penDownPos.SetValue( str(self.nextPanel.pos) )
+ self.nextPanel.nextPanel.downPos = self.pos
+
+ def hanBtnApplyUp(self, event): # wxGlade: Wizard_Page2.<event_handler>
+ self.pos = int( self.text_penUpPos.GetValue() )
+ reprap.cartesian.z.seek(self.pos)
+ self.nextPanel.pos = self.pos
+ self.nextPanel.text_penDownPos.SetValue( str(self.nextPanel.pos) )
+ self.nextPanel.nextPanel.downPos = self.pos
+
+# end of class Wizard_Page2
+
+
+class Wizard_Page3(wx.Panel):
+ def __init__(self, *args, **kwds):
+ # begin wxGlade: Wizard_Page3.__init__
+ kwds["style"] = wx.TAB_TRAVERSAL
+ wx.Panel.__init__(self, *args, **kwds)
+ self.sizer_25_staticbox = wx.StaticBox(self, -1, "Pen Position")
+ self.sizer_16_staticbox = wx.StaticBox(self, -1, "Pen Down Position")
+ self.sizer_24_staticbox = wx.StaticBox(self, -1, "Move Pen")
+ self.label_19 = wx.StaticText(self, -1, "Use the 'Up' and 'Down' buttons, or enter a value manually to position the pen where it is just making contact with the paper.")
+ self.button_stepUp_dp = wx.Button(self, wx.ID_UP, "")
+ self.button_stepDown_dp = wx.Button(self, wx.ID_DOWN, "")
+ self.text_penDownPos = wx.TextCtrl(self, -1, "0")
+ self.button_apply_dp = wx.Button(self, wx.ID_APPLY, "")
+
+ self.__set_properties()
+ self.__do_layout()
+
+ self.Bind(wx.EVT_BUTTON, self.OnBtnStepUp, self.button_stepUp_dp)
+ self.Bind(wx.EVT_BUTTON, self.OnBtnStepDown, self.button_stepDown_dp)
+ self.Bind(wx.EVT_BUTTON, self.hanBtnApplyDown, self.button_apply_dp)
+ # end wxGlade
+
+ self.pos = 0
+
+ def __set_properties(self):
+ # begin wxGlade: Wizard_Page3.__set_properties
+ pass
+ # end wxGlade
+
+ def __do_layout(self):
+ # begin wxGlade: Wizard_Page3.__do_layout
+ sizer_16 = wx.StaticBoxSizer(self.sizer_16_staticbox, wx.VERTICAL)
+ sizer_25 = wx.StaticBoxSizer(self.sizer_25_staticbox, wx.VERTICAL)
+ sizer_14 = wx.BoxSizer(wx.HORIZONTAL)
+ sizer_24 = wx.StaticBoxSizer(self.sizer_24_staticbox, wx.VERTICAL)
+ sizer_16.Add(self.label_19, 0, wx.ALL|wx.EXPAND|wx.ADJUST_MINSIZE, 12)
+ sizer_24.Add(self.button_stepUp_dp, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0)
+ sizer_24.Add(self.button_stepDown_dp, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0)
+ sizer_16.Add(sizer_24, 0, wx.ALL|wx.EXPAND, 6)
+ sizer_14.Add(self.text_penDownPos, 1, wx.ADJUST_MINSIZE, 0)
+ sizer_14.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_14.Add(self.button_apply_dp, 0, wx.ADJUST_MINSIZE, 0)
+ sizer_25.Add(sizer_14, 1, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL, 0)
+ sizer_16.Add(sizer_25, 0, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 6)
+ self.SetSizer(sizer_16)
+ sizer_16.Fit(self)
+ # end wxGlade
+
+ def setNextPanel(self, panel):
+ self.nextPanel = panel
+
+ def OnBtnStepUp(self, event): # wxGlade: Wizard_Page3.<event_handler>
+ self.pos = reprap.cartesian.z.getPos()
+ self.pos -= 1
+ reprap.cartesian.z.seek(self.pos)
+ self.text_penDownPos.SetValue( str(self.pos) )
+ self.nextPanel.upPos = self.pos
+
+ def OnBtnStepDown(self, event): # wxGlade: Wizard_Page3.<event_handler>
+ self.pos = reprap.cartesian.z.getPos()
+ self.pos += 1
+ reprap.cartesian.z.seek(self.pos)
+ self.text_penDownPos.SetValue( str(self.pos) )
+ self.nextPanel.upPos = self.pos
+
+ def hanBtnApplyDown(self, event): # wxGlade: Wizard_Page3.<event_handler>
+ self.pos = int( self.text_penDownPos.GetValue() )
+ reprap.cartesian.z.seek(self.pos)
+ self.nextPanel.upPos = self.pos
+
+# end of class Wizard_Page3
+
+
+class Wizard_Page4(wx.Panel):
+ def __init__(self, *args, **kwds):
+ # begin wxGlade: Wizard_Page4.__init__
+ kwds["style"] = wx.TAB_TRAVERSAL
+ wx.Panel.__init__(self, *args, **kwds)
+ self.sizer_17_staticbox = wx.StaticBox(self, -1, "Test")
+ self.label_18 = wx.StaticText(self, -1, "Test the pen positons with the buttons below.")
+ self.button_PenUp = wx.Button(self, -1, "Test Pen Up")
+ self.button_PenDown = wx.Button(self, -1, "Test Pen Down")
+
+ self.__set_properties()
+ self.__do_layout()
+
+ self.Bind(wx.EVT_BUTTON, self.OnBtnPenUp, self.button_PenUp)
+ self.Bind(wx.EVT_BUTTON, self.OnBtnPenDown, self.button_PenDown)
+ # end wxGlade
+ self.upPos = self.downPos = 0
+
+ def __set_properties(self):
+ # begin wxGlade: Wizard_Page4.__set_properties
+ pass
+ # end wxGlade
+
+ def __do_layout(self):
+ # begin wxGlade: Wizard_Page4.__do_layout
+ sizer_17 = wx.StaticBoxSizer(self.sizer_17_staticbox, wx.VERTICAL)
+ sizer_21_copy = wx.BoxSizer(wx.VERTICAL)
+ sizer_17.Add(self.label_18, 0, wx.ALL|wx.EXPAND|wx.ADJUST_MINSIZE, 12)
+ sizer_21_copy.Add(self.button_PenUp, 0, wx.EXPAND, 0)
+ sizer_21_copy.Add(self.button_PenDown, 0, wx.EXPAND, 0)
+ sizer_17.Add(sizer_21_copy, 1, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 51)
+ self.SetSizer(sizer_17)
+ sizer_17.Fit(self)
+ # end wxGlade
+
+ def setNextPanel(self, panel):
+ self.nextPanel = panel
+
+ def OnBtnPenUp(self, event): # wxGlade: Wizard_Page4.<event_handler>
+ reprap.cartesian.z.seek(self.upPos)
+
+ def OnBtnPenDown(self, event): # wxGlade: Wizard_Page4.<event_handler>
+ reprap.cartesian.z.seek(self.downPos)
+
+# end of class Wizard_Page4
+
+#Derived from
+#http://wiki.wxpython.org/WizardFromWxGlade
+class PenSetupWizard(wx.wizard.Wizard):
+ """
+ Wizard that can be built up from panel classes
+ generated by wxGlade
+ """
+ def __init__(self, parent, id=-1,
+ title=wx.EmptyString,
+ bitmap=wx.NullBitmap,
+ *args, **kw):
+
+ wx.wizard.Wizard.__init__(self, parent, id, title, bitmap, *args, **kw)
+ self.prevPanel = None
+ self.panels = []
+ def addPages(self, pages):
+ for name, pageClass in pages:
+ self.addPage(name, pageClass)
+ return
+
+ def addPage(self, attrname, panelClass):
+
+ # create wizard page object, and add on
+ # instance of our panel class to it
+ page = wx.wizard.WizardPageSimple(self)
+ page.sizer = wx.BoxSizer(wx.VERTICAL)
+ #page.sizer = wx.BoxSizer(wx.HORIZONTAL)
+ pageInst = panelClass(page, -1)
+ #page.sizer.Add(pageInst, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+ page.sizer.Add(pageInst, 1, wx.EXPAND, 0)
+ page.SetSizer(page.sizer)
+ #page.sizer.Fit(self)
+ #self.Layout()
+ #self.Centre()
+ # save the panel instance as named attribute
+ setattr(self, attrname, pageInst)
+ print "newp", page
+ print "prevp", self.prevPanel
+ #page.nextPanel = False
+ # chain to previous, if this is not the first page
+ if self.prevPanel:
+ #t.prevPanel = self.prevPanel
+ self.prevPanelInst.setNextPanel(pageInst)
+ wx.wizard.WizardPageSimple_Chain(self.prevPanel, page)
+ else:
+ self.firstPanel = page
+ self.panels.append(pageInst)
+ # remember this as 'previous' page, for adding/chaining the next
+ self.prevPanel = page
+ self.prevPanelInst = pageInst
+
+ def run(self):
+ return self.RunWizard(self.firstPanel)
+ def getPenPositions(self):
+ return self.panels[3].upPos, self.panels[3].downPos
+
+
+class PenSetup(wx.Dialog):
+ def __init__(self, *args, **kwds):
+ # begin wxGlade: PenSetup.__init__
+ kwds["style"] = wx.DEFAULT_DIALOG_STYLE
+ wx.Dialog.__init__(self, *args, **kwds)
+ self.notebook_Wizard = wx.Notebook(self, -1, style=0)
+ self.pane_Reset = Wizard_Page1(self.notebook_Wizard, -1)
+ self.pane_PenUp = Wizard_Page2(self.notebook_Wizard, -1)
+ self.pane_PenDown = Wizard_Page3(self.notebook_Wizard, -1)
+ self.pane_Test = Wizard_Page4(self.notebook_Wizard, -1)
+
+ self.__set_properties()
+ self.__do_layout()
+ # end wxGlade
+ self.penUp = False
+ self.downPos = 0
+
+ def __set_properties(self):
+ # begin wxGlade: PenSetup.__set_properties
+ self.SetTitle("Pen Plot Setup")
+ _icon = wx.EmptyIcon()
+ _icon.CopyFromBitmap(wx.Bitmap("/usr/share/reprap/icons/reprap.png", wx.BITMAP_TYPE_ANY))
+ self.SetIcon(_icon)
+ # end wxGlade
+
+ def __do_layout(self):
+ # begin wxGlade: PenSetup.__do_layout
+ sizer_13 = wx.BoxSizer(wx.HORIZONTAL)
+ self.notebook_Wizard.AddPage(self.pane_Reset, "Reset")
+ self.notebook_Wizard.AddPage(self.pane_PenUp, "Pen Up Position")
+ self.notebook_Wizard.AddPage(self.pane_PenDown, "Pen Down Position")
+ self.notebook_Wizard.AddPage(self.pane_Test, "Test")
+ sizer_13.Add(self.notebook_Wizard, 1, wx.EXPAND, 0)
+ self.SetSizer(sizer_13)
+ sizer_13.Fit(self)
+ self.Layout()
+ self.Centre()
+ # end wxGlade
+
+ self.downPos = reprap.cartesian.z.getPos()
+ self.text_penDownPos.SetValue( str(self.downPos) )
+ self.penUP = False
+
+ def OnBtnStepUp(self, event): # wxGlade: PenSetup.<event_handler>
+ if self.penUp:
+ print "TODO penup changed"
+ else:
+ self.downPos = int( self.text_penDownPos.GetValue() )
+ self.downPos = self.downPos - 1
+ self.text_penDownPos.SetValue( str(self.downPos) )
+ reprap.cartesian.z.seek(self.downPos)
+
+ def OnBtnStepDown(self, event): # wxGlade: PenSetup.<event_handler>
+ if self.penUp:
+ print "TODO penup changed"
+ else:
+ self.downPos = int( self.text_penDownPos.GetValue() )
+ self.downPos = self.downPos + 1
+ self.text_penDownPos.SetValue( str(self.downPos) )
+ reprap.cartesian.z.seek(self.downPos)
+
+ def OnBtnPenUp(self, event): # wxGlade: PenSetup.<event_handler>
+ self.upPos = int( self.text_penUpPos.GetValue() )
+ self.downPos = int( self.text_penDownPos.GetValue() )
+ if not self.penUp:
+ self.downPos = reprap.cartesian.z.getPos()
+ if self.downPos:
+ print "set dp", self.downPos, "moving to", self.downPos - 30
+ reprap.cartesian.z.seek( self.downPos - 30 )
+ self.penUp = True
+ else:
+ print "err"
+
+ def OnBtnOk(self, event): # wxGlade: PenSetup.<event_handler>
+ self.EndModal(wx.OK)
+
+
+ def OnBtnPenDown(self, event): # wxGlade: PenSetup.<event_handler>
+ self.upPos = int( self.text_penUpPos.GetValue() )
+ self.downPos = int( self.text_penDownPos.GetValue() )
+ if self.penUp:
+ reprap.cartesian.z.seek( self.downPos )
+ self.penUp = False
+
+ def getDownPos(self):
+ return self.downPos
+
+ def hanBtnReset(self, event): # wxGlade: PenSetup.<event_handler>
+ print "Event handler `hanBtnReset' not implemented"
+ event.Skip()
+
+ def hanBtnApplyUp(self, event): # wxGlade: PenSetup.<event_handler>
+ print "Event handler `hanBtnApplyUp' not implemented"
+ event.Skip()
+
+ def hanBtnApplyDown(self, event): # wxGlade: PenSetup.<event_handler>
+ print "Event handler `hanBtnApplyDown' not implemented"
+ event.Skip()
+
+# end of class PenSetup
+
+
+class programPreferences:
+ def __init__(self):
+ # default values for preferences
+ self.stepsPerMillimeterX = 30
+ self.stepsPerMillimeterY = 30
+ self.limitX = 2523 # 84.1mm
+ self.limitY = 2000 # 66.7mm
+ self.enableLimit = True
+ self.plotOffsetX = float(10)
+ self.plotOffsetY = float(10)
+ self.torque = 90 # 83 (old values)
+ self.speed = 230 # 220
+ self.fillDensity = 5 # 4
+ self.lineDelay = float(0)
+ self.debug = False
+ self.circleResolution = float(3)
+ self.penUpPos = 0
+ self.penDownPos = 0
+ #TODO - add pen idle height, and proper pen config
+ #TODO - add dxf scale
+ #TODO - put serial stuff in preferences
+
+ if os.system=="win32":
+ self.homeDir = os.environ.get("USERPROFILE")
+ else:
+ self.homeDir = os.environ.get("HOME")
+ self.confFolder = "/.pyRepRap"
+ self.confFile = "pyRepRap.conf"
+
+ def load(self):
+ # Load settings, create file if it does not exist
+ if os.path.exists( self.homeDir + self.confFolder + "/" + self.confFile ):
+ f = open( self.homeDir + self.confFolder + "/" + self.confFile, "r" )
+ for l in f.readlines():
+ parts = l.split("=")
+ command, value = parts[0], parts[1][ : -1 ]
+ #print "'" + command + "', '" + value + "'"
+ if command == "stepsPerMillimeterX":
+ self.stepsPerMillimeterX = int(value)
+ elif command == "stepsPerMillimeterY":
+ self.stepsPerMillimeterY = int(value)
+ elif command == "limitX":
+ self.limitX = int(value)
+ elif command == "limitY":
+ self.limitY = int(value)
+ elif command == "enableLimit":
+ if value == "True":
+ self.enableLimit = True
+ else:
+ self.enableLimit = False
+ elif command == "plotOffsetX":
+ self.plotOffsetX = float(value)
+ elif command == "plotOffsetY":
+ self.plotOffsetY = float(value)
+ elif command == "torque":
+ self.torque = int(value)
+ elif command == "speed":
+ self.speed = int(value)
+ elif command == "fillDensity":
+ self.fillDensity = int(value)
+ elif command == "lineDelay":
+ self.lineDelay = float(value)
+ elif command == "debug":
+ if value == "True":
+ self.debug = True
+ else:
+ self.debug = False
+ elif command == "circleResolution":
+ self.circleResolution = float(value)
+ elif command == "penUpPos":
+ self.penUpPos = int(value)
+ elif command == "penDownPos":
+ self.penDownPos = int(value)
+ f.close()
+ else:
+ print "No configuration file found. Creating '" + self.homeDir + self.confFolder + "/" + self.confFile + "'"
+ if not os.path.exists( self.homeDir + self.confFolder ):
+ os.mkdir( self.homeDir + self.confFolder )
+ self.save()
+
+ def save(self):
+ commandLookup = { "stepsPerMillimeterX" : self.stepsPerMillimeterX, "stepsPerMillimeterY" : self.stepsPerMillimeterY, "limitX" : self.limitX, "limitY" : self.limitY, "enableLimit" : self.enableLimit, "plotOffsetX" : self.plotOffsetX , "plotOffsetY" : self.plotOffsetY, "torque" : self.torque, "speed" : self.speed, "fillDensity" : self.fillDensity, "lineDelay" : self.lineDelay, "debug" : self.debug, "circleResolution" : self.circleResolution, "penUpPos" : self.penUpPos, "penDownPos" : self.penDownPos }
+ f = open( self.homeDir + self.confFolder + "/" + self.confFile, "w" )
+ fileText = ""
+ for c in commandLookup.keys():
+ fileText += c + "=" + str( commandLookup[c] ) + "\n"
+ f.write( fileText )
+ f.close()
+
+# Dialog class for preferences
+class PreferencesDialog(wx.Dialog):
+ def __init__(self, *args, **kwds):
+ # begin wxGlade: PreferencesDialog.__init__
+ kwds["style"] = wx.DEFAULT_DIALOG_STYLE
+ wx.Dialog.__init__(self, *args, **kwds)
+ self.sizer_7_staticbox = wx.StaticBox(self, -1, "")
+ self.label_4 = wx.StaticText(self, -1, "Steps per mm : ")
+ self.label_2 = wx.StaticText(self, -1, "X :")
+ self.text_stepPermmX = wx.TextCtrl(self, -1, "")
+ self.label_3 = wx.StaticText(self, -1, "Y :")
+ self.text_stepPermmY = wx.TextCtrl(self, -1, "")
+ self.label_14 = wx.StaticText(self, -1, "Pen Positions :")
+ self.label_17 = wx.StaticText(self, -1, "Up :")
+ self.text_penUpPos = wx.TextCtrl(self, -1, "")
+ self.label_21 = wx.StaticText(self, -1, "Down :")
+ self.text_penDownPos = wx.TextCtrl(self, -1, "")
+ self.label_5 = wx.StaticText(self, -1, "Print area limit (steps) : ")
+ self.label_6 = wx.StaticText(self, -1, "X :")
+ self.text_limitX = wx.TextCtrl(self, -1, "")
+ self.label_7 = wx.StaticText(self, -1, "Y :")
+ self.text_limitY = wx.TextCtrl(self, -1, "")
+ self.checkbox_enableLimit = wx.CheckBox(self, -1, "Enable")
+ self.label_8 = wx.StaticText(self, -1, "Plot offset (mm) : ")
+ self.label_9 = wx.StaticText(self, -1, "X : ")
+ self.text_offsetX = wx.TextCtrl(self, -1, "")
+ self.label_10 = wx.StaticText(self, -1, "Y :")
+ self.text_offsetY = wx.TextCtrl(self, -1, "")
+ self.label_11 = wx.StaticText(self, -1, "Fill density (lines / mm) :")
+ self.text_fillDensity = wx.TextCtrl(self, -1, "")
+ self.label_16 = wx.StaticText(self, -1, "Circle resolution (lines / mm in c)")
+ self.text_circleResolution = wx.TextCtrl(self, -1, "")
+ self.label_12 = wx.StaticText(self, -1, "Move speed (0-255) :")
+ self.text_speed = wx.TextCtrl(self, -1, "")
+ self.label_13 = wx.StaticText(self, -1, "Torque (%) :")
+ self.text_torque = wx.TextCtrl(self, -1, "")
+ self.label_1 = wx.StaticText(self, -1, "Delay between lines (seconds) :")
+ self.text_lineDelay = wx.TextCtrl(self, -1, "")
+ self.checkbox_debug = wx.CheckBox(self, -1, "Debug")
+ self.button_Ok = wx.Button(self, wx.ID_OK, "")
+ self.button_Cancel = wx.Button(self, wx.ID_CANCEL, "")
+
+ self.__set_properties()
+ self.__do_layout()
+
+ self.Bind(wx.EVT_BUTTON, self.hanBtnOk, self.button_Ok)
+ self.Bind(wx.EVT_BUTTON, self.hanBtnCancel, self.button_Cancel)
+ # end wxGlade
+
+ def __set_properties(self):
+ # begin wxGlade: PreferencesDialog.__set_properties
+ self.SetTitle("RepRap Gerber Plotter - Preferences")
+ _icon = wx.EmptyIcon()
+ _icon.CopyFromBitmap(wx.Bitmap("/usr/share/reprap/icons/reprap.png", wx.BITMAP_TYPE_ANY))
+ self.SetIcon(_icon)
+ self.checkbox_enableLimit.SetValue(1)
+ # end wxGlade
+
+ def __do_layout(self):
+ # begin wxGlade: PreferencesDialog.__do_layout
+ sizer_7 = wx.StaticBoxSizer(self.sizer_7_staticbox, wx.VERTICAL)
+ sizer_5 = wx.BoxSizer(wx.VERTICAL)
+ sizer_7_copy = wx.BoxSizer(wx.HORIZONTAL)
+ sizer_4 = wx.BoxSizer(wx.HORIZONTAL)
+ sizer_12 = wx.BoxSizer(wx.HORIZONTAL)
+ sizer_11 = wx.BoxSizer(wx.HORIZONTAL)
+ sizer_15 = wx.BoxSizer(wx.HORIZONTAL)
+ sizer_10 = wx.BoxSizer(wx.HORIZONTAL)
+ sizer_9 = wx.BoxSizer(wx.HORIZONTAL)
+ sizer_8 = wx.BoxSizer(wx.HORIZONTAL)
+ sizer_18 = wx.BoxSizer(wx.HORIZONTAL)
+ sizer_6 = wx.BoxSizer(wx.HORIZONTAL)
+ sizer_6.Add(self.label_4, 0, wx.ADJUST_MINSIZE, 0)
+ sizer_6.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_6.Add(self.label_2, 0, wx.ADJUST_MINSIZE, 0)
+ sizer_6.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_6.Add(self.text_stepPermmX, 1, 0, 0)
+ sizer_6.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_6.Add(self.label_3, 0, wx.ADJUST_MINSIZE, 0)
+ sizer_6.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_6.Add(self.text_stepPermmY, 1, 0, 0)
+ sizer_5.Add(sizer_6, 1, wx.EXPAND, 0)
+ sizer_18.Add(self.label_14, 0, wx.ADJUST_MINSIZE, 0)
+ sizer_18.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_18.Add(self.label_17, 0, wx.ADJUST_MINSIZE, 0)
+ sizer_18.Add(self.text_penUpPos, 1, wx.ADJUST_MINSIZE, 0)
+ sizer_18.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_18.Add(self.label_21, 0, wx.ADJUST_MINSIZE, 0)
+ sizer_18.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_18.Add(self.text_penDownPos, 1, wx.ADJUST_MINSIZE, 0)
+ sizer_5.Add(sizer_18, 1, wx.EXPAND, 0)
+ sizer_8.Add(self.label_5, 0, wx.ADJUST_MINSIZE, 0)
+ sizer_8.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_8.Add(self.label_6, 0, wx.ADJUST_MINSIZE, 0)
+ sizer_8.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_8.Add(self.text_limitX, 1, wx.ADJUST_MINSIZE, 0)
+ sizer_8.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_8.Add(self.label_7, 0, wx.ADJUST_MINSIZE, 0)
+ sizer_8.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_8.Add(self.text_limitY, 1, wx.ADJUST_MINSIZE, 0)
+ sizer_8.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_8.Add(self.checkbox_enableLimit, 0, wx.ADJUST_MINSIZE, 0)
+ sizer_5.Add(sizer_8, 1, wx.EXPAND, 0)
+ sizer_9.Add(self.label_8, 0, wx.ADJUST_MINSIZE, 0)
+ sizer_9.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_9.Add(self.label_9, 0, wx.ADJUST_MINSIZE, 0)
+ sizer_9.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_9.Add(self.text_offsetX, 1, wx.ADJUST_MINSIZE, 0)
+ sizer_9.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_9.Add(self.label_10, 0, wx.ADJUST_MINSIZE, 0)
+ sizer_9.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_9.Add(self.text_offsetY, 1, wx.ADJUST_MINSIZE, 0)
+ sizer_5.Add(sizer_9, 1, wx.EXPAND, 0)
+ sizer_10.Add(self.label_11, 0, wx.ADJUST_MINSIZE, 0)
+ sizer_10.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_10.Add(self.text_fillDensity, 1, wx.ADJUST_MINSIZE, 0)
+ sizer_5.Add(sizer_10, 1, wx.EXPAND, 0)
+ sizer_15.Add(self.label_16, 0, wx.ADJUST_MINSIZE, 0)
+ sizer_15.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_15.Add(self.text_circleResolution, 1, wx.ADJUST_MINSIZE, 0)
+ sizer_5.Add(sizer_15, 1, wx.EXPAND, 0)
+ sizer_11.Add(self.label_12, 0, wx.ADJUST_MINSIZE, 0)
+ sizer_11.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_11.Add(self.text_speed, 1, wx.ADJUST_MINSIZE, 0)
+ sizer_5.Add(sizer_11, 1, wx.EXPAND, 0)
+ sizer_12.Add(self.label_13, 0, wx.ADJUST_MINSIZE, 0)
+ sizer_12.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_12.Add(self.text_torque, 1, wx.ADJUST_MINSIZE, 0)
+ sizer_5.Add(sizer_12, 1, wx.EXPAND, 0)
+ sizer_4.Add(self.label_1, 0, wx.ADJUST_MINSIZE, 0)
+ sizer_4.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_4.Add(self.text_lineDelay, 1, wx.ADJUST_MINSIZE, 0)
+ sizer_5.Add(sizer_4, 1, wx.EXPAND, 0)
+ sizer_5.Add(self.checkbox_debug, 0, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
+ sizer_5.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_7_copy.Add(self.button_Ok, 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
+ sizer_7_copy.Add(self.button_Cancel, 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
+ sizer_5.Add(sizer_7_copy, 1, wx.EXPAND, 0)
+ sizer_7.Add(sizer_5, 1, wx.ALL|wx.EXPAND|wx.ADJUST_MINSIZE, 16)
+ self.SetSizer(sizer_7)
+ sizer_7.Fit(self)
+ self.Layout()
+ self.Centre()
+ # end wxGlade
+
+
+ # Set values of frame control
+ def setPrefValues(self, prefs):
+ self.preferences = prefs
+ self.text_stepPermmX.SetValue( str(prefs.stepsPerMillimeterX) )
+ self.text_stepPermmY.SetValue( str(prefs.stepsPerMillimeterY) )
+ self.text_limitX.SetValue( str(prefs.limitX) )
+ self.text_limitY.SetValue( str(prefs.limitY) )
+ self.checkbox_enableLimit.SetValue( prefs.enableLimit )
+ self.text_offsetX.SetValue( str(prefs.plotOffsetX) )
+ self.text_offsetY.SetValue( str(prefs.plotOffsetY) )
+ self.text_torque.SetValue( str(prefs.torque) )
+ self.text_speed.SetValue( str(prefs.speed) )
+ self.text_fillDensity.SetValue( str(prefs.fillDensity) )
+ self.text_lineDelay.SetValue( str(prefs.lineDelay) )
+ self.checkbox_debug.SetValue( prefs.debug )
+ self.text_circleResolution.SetValue( str(prefs.circleResolution) )
+ self.text_penUpPos.SetValue( str(prefs.penUpPos) )
+ self.text_penDownPos.SetValue( str(prefs.penDownPos) )
+
+ def getPreferences(self):
+ return self.preferences
+
+ # User clicked OK
+ def hanBtnOk(self, event): # wxGlade: PreferencesDialog.<event_handler>
+ self.preferences.stepsPerMillimeterX = int( self.text_stepPermmX.GetValue() )
+ self.preferences.stepsPerMillimeterY = int( self.text_stepPermmY.GetValue() )
+ self.preferences.limitX = int( self.text_limitX.GetValue() )
+ self.preferences.limitY = int( self.text_limitY.GetValue() )
+ self.preferences.enableLimit = self.checkbox_enableLimit.GetValue()
+ self.preferences.plotOffsetX = float( self.text_offsetX.GetValue() )
+ self.preferences.plotOffsetY = float( self.text_offsetY.GetValue() )
+ self.preferences.torque = int( self.text_torque.GetValue() )
+ self.preferences.speed = int( self.text_speed.GetValue() )
+ self.preferences.fillDensity = int( self.text_fillDensity.GetValue() )
+ self.preferences.lineDelay = float( self.text_lineDelay.GetValue() )
+ self.preferences.debug = self.checkbox_debug.GetValue()
+ self.preferences.circleResolution = float( self.text_circleResolution.GetValue() )
+ self.preferences.penUpPos = int( self.text_penUpPos.GetValue() )
+ self.preferences.penDownPos = int( self.text_penDownPos.GetValue() )
+ self.EndModal(wx.OK)
+
+ # User clicked Cancel
+ def hanBtnCancel(self, event): # wxGlade: PreferencesDialog.<event_handler>
+ self.preferences = False
+ self.EndModal(wx.CANCEL)
+# end of class PreferencesDialog
+
+
+class prefFrame(wx.Frame):
+ def __init__(self, *args, **kwds):
+ # content of this block not found: did you rename this class?
+ pass
+ def setParent( self, parent ):
+ self.parent = parent
+ def __set_properties(self):
+ # content of this block not found: did you rename this class?
+ pass
+
+ def __do_layout(self):
+ # content of this block not found: did you rename this class?
+ pass
+
+# end of class prefFrame
+
+# A set of lines for drawing on the screen TODO - put draw back in
+class lineSet:
+ def __init__(self, parent, colour):
+ self.parent = parent
+ self.colour = colour
+ self.clear()
+ def setColour(colour):
+ self.colour = colour
+ self.tableChanged = True
+ def addLine(self, line):
+ self.lines.append(line)
+ #self.parent.draw() #not ideal
+ #pygame.display.flip()
+ self.tableChanged = True
+ def getLines(self):
+ return self.lines
+ def clear(self):
+ self.lines = []
+ self.tableChanged = True
+ def hasChanged(self):
+ if self.tableChanged:
+ self.tableChanged = False
+ return True
+ else:
+ return False
+
+
+# Class for pygame canvas
+class DrawCanvas(wxpygame.wxSDLPanel):
+ def __init__( self, parent, ID=-1 ):
+ wxpygame.wxSDLPanel.__init__( self, parent,ID )
+ self.previewScale = float(0.5)
+ self.offsetX, self.offsetY = 20, 20 # make this change by dragging mouse in window
+ self.refresh()
+ self.plotLines = []
+ self.black = 0, 0, 0
+ self.grey = 160, 160, 160
+ self.backroundColour = 255, 255, 255
+ self.plotColour = self.black
+ self.baseColour = 166, 211, 166
+ self.previewLines = lineSet( self, self.grey )
+ self.plotLines = lineSet( self, self.black )
+
+ # Referesh
+ def refresh(self):
+ self.printArea = 0, 0, reprap.cartesian.x.limit, reprap.cartesian.y.limit
+
+ # Simple coordiante manipulation
+ def scaleRect( self, rect, scale ):
+ x1, y1, x2, y2 = rect
+ scale = float(scale)
+ return int( float(x1) * scale ), int( float(y1) * scale ), int( float(x2) * scale ), int( float(y2) * scale )
+ def offsetRect( self, rect, x, y ):
+ x1, y1, x2, y2 = rect
+ return x1 + x, y1 + y, x2, y2
+ def offsetLine(self, rect, x, y):
+ x1, y1, x2, y2 = rect
+ return x1 + x, y1 + y, x2 + x, y2 + y
+
+ # Draw plot to widget
+ def draw( self ):
+ surface = self.getSurface()
+ if not surface is None:
+ surface.fill( self.backroundColour )
+ pygame.draw.rect( surface, self.baseColour, self.offsetRect( self.scaleRect( self.printArea, self.previewScale ), self.offsetX, self.offsetY ), 0)
+
+ for l in self.previewLines.getLines():
+ x1, y1, x2, y2 = self.offsetLine( self.scaleRect( l, self.previewScale ), self.offsetX, self.offsetY )
+ pygame.draw.line( surface, self.previewLines.colour, (x1, y1), (x2, y2) )
+ for l in self.plotLines.getLines():
+ x1, y1, x2, y2 = self.offsetLine( self.scaleRect( l, self.previewScale ), self.offsetX, self.offsetY )
+ pygame.draw.line( surface, self.plotLines.colour, (x1, y1), (x2, y2) )
+ for event in pygame.event.get():
+ if event.type == pygame.QUIT:
+ sys.exit()
+ pygame.display.flip()
+ #if self.previewLines.hasChanged() or self.plotLines.hasChanged():
+ # self.update()
+
+ # Change draw offset to allow dragging of plot
+ def MouseMove(self, event):
+ if event.LeftIsDown():
+ x, y = event.GetPosition()
+ if event.Dragging():
+ self.offsetX, self.offsetY = x + self.moveDeltaX, y + self.moveDeltaY
+ # Record offsets for use in drag movement
+ def OnMouseDown(self, event):
+ x, y = event.GetPosition()
+ self.moveDeltaX, self.moveDeltaY = self.offsetX - x, self.offsetY - y
+ def OnMouseUp(self, event):
+ pass
+ # When mouse wheel moved, zoom in or out
+ def OnMouseWheel(self, event):
+ if event.GetWheelRotation() > 0:
+ self.previewScale = self.previewScale + 0.05
+ elif self.previewScale >= 0.1:
+ self.previewScale = self.previewScale - 0.05
+
+
+# Main frame class
+class MyFrame(wx.Frame):
+ def __init__(self, *args, **kwds):
+ # begin wxGlade: MyFrame.__init__
+ kwds["style"] = wx.DEFAULT_FRAME_STYLE
+ wx.Frame.__init__(self, *args, **kwds)
+
+ # Menu Bar
+ self.frmMain_menubar = wx.MenuBar()
+ self.mnuFile = wx.Menu()
+ self.mnuOpen = wx.MenuItem(self.mnuFile, 0, "&Open", "", wx.ITEM_NORMAL)
+ self.mnuFile.AppendItem(self.mnuOpen)
+ self.mnuQuit = wx.MenuItem(self.mnuFile, 1, "&Quit", "", wx.ITEM_NORMAL)
+ self.mnuFile.AppendItem(self.mnuQuit)
+ self.frmMain_menubar.Append(self.mnuFile, "&File")
+ wxglade_tmp_menu = wx.Menu()
+ wxglade_tmp_menu.Append(10, "Pr&eferences", "", wx.ITEM_NORMAL)
+ self.frmMain_menubar.Append(wxglade_tmp_menu, "&Edit")
+ wxglade_tmp_menu = wx.Menu()
+ self.mnuAbout = wx.MenuItem(wxglade_tmp_menu, 40, "&About", "", wx.ITEM_NORMAL)
+ wxglade_tmp_menu.AppendItem(self.mnuAbout)
+ self.frmMain_menubar.Append(wxglade_tmp_menu, "&Help")
+ self.SetMenuBar(self.frmMain_menubar)
+ # Menu Bar end
+ self.frmMain_statusbar = self.CreateStatusBar(1, 0)
+
+ # Tool Bar
+ self.frmMain_toolbar = wx.ToolBar(self, -1, style=wx.TB_HORIZONTAL|wx.TB_TEXT)
+ self.SetToolBar(self.frmMain_toolbar)
+ self.frmMain_toolbar.AddLabelTool(100, "Open", wx.Bitmap("/usr/share/reprap/icons/go-home.png", wx.BITMAP_TYPE_ANY), wx.NullBitmap, wx.ITEM_NORMAL, "Open Gerber File", "")
+ self.frmMain_toolbar.AddSeparator()
+ self.frmMain_toolbar.AddLabelTool(110, "Enable RepRap", wx.Bitmap("/usr/share/reprap/icons/connect_no.png", wx.BITMAP_TYPE_ANY), wx.Bitmap("/usr/share/reprap/icons/document-open.png", wx.BITMAP_TYPE_ANY), wx.ITEM_CHECK, "", "")
+ self.frmMain_toolbar.AddLabelTool(111, "Reset", wx.Bitmap("/usr/share/reprap/icons/go-home.png", wx.BITMAP_TYPE_ANY), wx.NullBitmap, wx.ITEM_NORMAL, "", "")
+ self.frmMain_toolbar.AddLabelTool(112, "Stop", wx.Bitmap("/usr/share/reprap/icons/media-playback-stop.png", wx.BITMAP_TYPE_ANY), wx.NullBitmap, wx.ITEM_NORMAL, "", "")
+ self.frmMain_toolbar.AddLabelTool(113, "Pen Setup", wx.Bitmap("/usr/share/reprap/icons/reprap.png", wx.BITMAP_TYPE_ANY), wx.NullBitmap, wx.ITEM_NORMAL, "", "")
+ self.frmMain_toolbar.AddSeparator()
+ self.frmMain_toolbar.AddLabelTool(120, "Plot", wx.Bitmap("/usr/share/reprap/icons/media-playback-start.png", wx.BITMAP_TYPE_ANY), wx.NullBitmap, wx.ITEM_NORMAL, "Plot to screen or RepRap", "")
+ self.frmMain_toolbar.AddSeparator()
+ # Tool Bar end
+ self.pygameCanvas = DrawCanvas(self, -1)
+
+ self.__set_properties()
+ self.__do_layout()
+
+ self.Bind(wx.EVT_MENU, self.hanMnuOpen, self.mnuOpen)
+ self.Bind(wx.EVT_MENU, self.hanMnuQuit, self.mnuQuit)
+ self.Bind(wx.EVT_MENU, self.hanMnuPreferences, id=10)
+ self.Bind(wx.EVT_MENU, self.hanMnuAbout, self.mnuAbout)
+ self.Bind(wx.EVT_TOOL, self.hanTBopen, id=100)
+ self.Bind(wx.EVT_TOOL, self.hanTBenableReprap, id=110)
+ self.Bind(wx.EVT_TOOL, self.hanTBhome, id=111)
+ self.Bind(wx.EVT_TOOL, self.hanTBstop, id=112)
+ self.Bind(wx.EVT_TOOL, self.hanTBpenSetup, id=113)
+ self.Bind(wx.EVT_TOOL, self.hanTBplot, id=120)
+ # end wxGlade
+
+ self.fileName = False
+ self.currentPlotter = False
+ self.reprapEnabled = False
+ self.preferences = programPreferences()
+ self.preferences.load()
+ reprap.cartesian.x.limit = self.preferences.limitX
+ reprap.cartesian.y.limit = self.preferences.limitY
+ self.pygameCanvas.refresh()
+
+ def __set_properties(self):
+ # begin wxGlade: MyFrame.__set_properties
+ self.SetTitle("RepRap Plotter")
+ _icon = wx.EmptyIcon()
+ _icon.CopyFromBitmap(wx.Bitmap("/usr/share/reprap/icons/reprap.png", wx.BITMAP_TYPE_ANY))
+ self.SetIcon(_icon)
+ self.SetSize((869, 579))
+ self.frmMain_statusbar.SetStatusWidths([-1])
+ # statusbar fields
+ frmMain_statusbar_fields = ["frmMain_statusbar"]
+ for i in range(len(frmMain_statusbar_fields)):
+ self.frmMain_statusbar.SetStatusText(frmMain_statusbar_fields[i], i)
+ self.frmMain_toolbar.Realize()
+ # end wxGlade
+
+ def __do_layout(self):
+ # begin wxGlade: MyFrame.__do_layout
+ sizer_main = wx.BoxSizer(wx.VERTICAL)
+ sizer_main.Add(self.pygameCanvas, 5, wx.EXPAND, 1)
+ self.SetSizer(sizer_main)
+ self.Layout()
+ self.Centre()
+ # end wxGlade
+
+ # custom functions
+ def dialogFilterString(self, extensions, name):
+ rText = name + " ("
+ for e in extensions:
+ rText += '*' + e + ';'
+ rText = rText[ :-1 ]
+ rText += ")|"
+ for e in extensions:
+ rText += '*' + e + ';'
+ rText = rText[ :-1 ]
+ return rText
+
+ def openFile(self):
+ filters = self.dialogFilterString( gerberplot.getSupportedFileExtensions(), gerberplot.getFileTitle() ) + '|'
+ filters += self.dialogFilterString( dxfplot.getSupportedFileExtensions() , dxfplot.getFileTitle() )
+ print filters
+ #filters = 'Gerber files (*.pho;*.gbl;*.gtl;*.gbs;*.gts;*.gbo;*.gto;*.gbr;*.gbx;*.phd;*.spl;*.art;*.top;*.bot)|*.pho;*.gbl;*.gtl;*.gbs;*.gts;*.gbo;*.gto;*.gbr;*.gbx;*.phd;*.spl;*.art;*.top;*.bot|DXF CAD files (*.dxf)|*.dxf|All files (*.*)|*.*'
+ dialog = wx.FileDialog ( None, message = 'Open Gerber File', wildcard = filters, style = wx.OPEN )
+ if dialog.ShowModal() == wx.ID_OK:
+ self.fileName = dialog.GetPath()
+ self.setStatusBar( "Opened File '" + self.fileName + "'" )
+ #else:
+ # print 'Nothing was selected.'
+ dialog.Destroy()
+
+ def plot(self):
+ if self.fileName:
+ self.setStatusBar( "Plotting File '" + self.fileName + "'" )
+
+ # The gerberPlotter class will append lines to lineDump (from another thread) resulting in them being drawn in pygameCanvas as they are plotted.
+ if self.reprapEnabled:
+ lineDump = self.pygameCanvas.plotLines
+ else:
+ lineDump = self.pygameCanvas.previewLines
+ lineDump.clear()
+
+ if self.fileName[ -4 : ].lower() == ".dxf":
+ # File is dxf
+ self.currentPlotter = dxfplot.plotter()
+ else:
+ # Assume file is gerber (temp)
+ self.currentPlotter = gerberplot.plotter()
+
+ offset = self.preferences.plotOffsetX, self.preferences.plotOffsetY
+ self.currentPlotter.setup( self.fileName, offset = offset, fillDensity = self.preferences.fillDensity, debug = self.preferences.debug, stepsPerMillimeter = ( self.preferences.stepsPerMillimeterX, self.preferences.stepsPerMillimeterY ), speed = self.preferences.speed, circleResolution = self.preferences.circleResolution )
+ self.currentPlotter.setLineDump(lineDump)
+ self.currentPlotter.setLineDelay(self.preferences.lineDelay)
+ self.currentPlotter.setReprap(self.reprapEnabled)
+ if self.reprapEnabled:
+ self.currentPlotter.setPenPositions(self.preferences.penUpPos, self.preferences.penDownPos)
+ self.currentPlotter.start()
+
+
+ #event handlers
+
+ def hanZoomScroll(self, event): # wxGlade: MyFrame.<event_handler>
+ self.pygameCanvas.previewScale = float( self.slider_zoom.GetValue() ) / 100
+ event.Skip()
+
+ def hanMnuOpen(self, event): # wxGlade: MyFrame.<event_handler>
+ self.openFile()
+ event.Skip()
+
+ def hanMnuQuit(self, event): # wxGlade: MyFrame.<event_handler>
+ wx.Exit()
+
+ def hanTBplot(self, event): # wxGlade: MyFrame.<event_handler>
+ self.plot()
+
+ def hanTBopen(self, event): # wxGlade: MyFrame.<event_handler>
+ self.openFile()
+
+ # User click enable reprap toggle button
+ def hanTBenableReprap(self, event): # wxGlade: MyFrame.<event_handler>
+ self.raprapEnabled = event.Checked()
+ if self.raprapEnabled:
+ #TODO - put serial stuff in preferences
+ # Prepare reprap for use
+ if reprap.openSerial( 0, 19200, 60 ): # Initialise serial port, here the first port (0) is used, timeout 60 seconds.
+ reprap.cartesian.x.active = True # These devices are present in network, will automatically scan in the future.
+ reprap.cartesian.y.active = True
+ reprap.cartesian.z.active = True
+ reprap.cartesian.x.setNotify()
+ reprap.cartesian.y.setNotify()
+ reprap.cartesian.z.setNotify()
+ reprap.cartesian.setMoveSpeed( int(self.preferences.speed) )
+ reprap.cartesian.setPower( int( self.preferences.torque * 0.63 ) )
+ print reprap.cartesian.getPos()
+ self.reprapEnabled = True
+ self.setStatusBar( "RepRap Enabled" )
+ else:
+ dlg = wx.MessageDialog( self, "You do not have the required permissions to access the serial port. Try granting your user permissions (recommended) or run as root (not recommended).", "pyRepRap Serial Port Error", wx.OK )
+ val = dlg.ShowModal()
+ dlg.Destroy()
+ wx.Exit()
+ else:
+ reprap.closeSerial()
+ self.reprapEnabled = False
+ self.setStatusBar( "RepRap Disabled" )
+
+ def hanTBstop(self, event): # wxGlade: MyFrame.<event_handler>
+ if self.reprapEnabled:
+ if self.currentPlotter:
+ self.currentPlotter.terminate()
+ self.currentPlotter.waitTerminate()
+ reprap.cartesian.stop()
+ reprap.cartesian.free()
+ event.Skip()
+
+ def hanMnuPreferences(self, event): # wxGlade: MyFrame.<event_handler>
+ dialogPref = PreferencesDialog(None, -1, "")
+ app.SetTopWindow(dialogPref)
+
+ dialogPref.setPrefValues( self.preferences )
+ dialogPref.ShowModal()
+ newPref = dialogPref.getPreferences()
+ if newPref:
+ self.preferences = newPref
+ if self.preferences.enableLimit:
+ reprap.cartesian.x.limit = self.preferences.limitX
+ reprap.cartesian.y.limit = self.preferences.limitY
+ else:
+ reprap.cartesian.x.limit = 9999999 # does not really disable limit, just makes it really big :)
+ reprap.cartesian.y.limit = 9999999
+ self.pygameCanvas.refresh()
+ dialogPref.Destroy()
+ self.preferences.save()
+
+ def hanMnuAbout(self, event): # wxGlade: MyFrame.<event_handler>
+ description = "RepRap Plotter is a program for plotting Gerber and CAD files on a RepRap machine."
+
+ licence = """Licenced under GNU v2 and the 'I'm not going to help you kill people licence'. The latter overrules the former.
+
+I'm not going to help you kill people licence v1:
+The use of this software in any form for any purposes relating to any form of military activity or
+research either directly or via subcontracts is strictly prohibited.
+Any company or organisation affiliated with any military organisations either directly or through
+subcontracts are strictly prohibited from using any part of this software.
+
+GNU licence:
+RepRap Plotter is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free Software Foundation;
+either version 2 of the License, or (at your option) any later version.
+
+RepRap Plotter is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See the GNU General Public License for more details. You should have received a copy of
+the GNU General Public License along with File Hunter; if not, write to
+the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA"""
+
+ info = wx.AboutDialogInfo()
+ #info.SetIcon(wx.Icon('icons/hunter.png', wx.BITMAP_TYPE_PNG))
+ info.SetName('About RepRap Plotter')
+ info.SetVersion('1.0')
+ info.SetDescription(description)
+ #info.SetCopyright('')
+ info.SetLicence(licence)
+ info.AddDeveloper('Stefan Blanke')
+ wx.AboutBox(info)
+
+ def hanTBhome(self, event): # wxGlade: MyFrame.<event_handler>
+ if self.reprapEnabled:
+ reprap.cartesian.homeReset( waitArrival = True ) #caused problems with false?
+ reprap.cartesian.free()
+ self.setStatusBar( "RepRap home reset complete" )
+ event.Skip()
+ def setStatusBar(self, text):
+ self.frmMain_statusbar.SetStatusText( text, 0 )
+ #self.frmMain_statusbar.SetStatusText( "pyRepRap", 1 )
+
+ def hanTBpenSetup(self, event): # wxGlade: MyFrame.<event_handler>
+ if self.reprapEnabled:
+ wizard = self.wizard = PenSetupWizard( parent=self, title="Pen Calibration", )
+ wizard.addPages( [ ("pane1", Wizard_Page1), ("pane2", Wizard_Page2), ("pane3", Wizard_Page3), ("pane4", Wizard_Page4), ], )
+ if wizard.run():
+ #self.penDownPos = dialogPen.getDownPos()
+ self.preferences.penUpPos, self.preferences.penDownPos = wizard.getPenPositions()
+ #print self.preferences.penUpPos, self.preferences.penDownPos
+ self.preferences.save()
+ wizard.Destroy()
+ else:
+ dlg = wx.MessageDialog( self, "RepRap must be enabled to configure pen position.", "pyRepRap Error", wx.OK )
+ val = dlg.ShowModal()
+ dlg.Destroy()
+
+# end of class MyFrame
+
+if len(sys.argv) <=1:
+ if __name__ == "__main__":
+ app = wx.PySimpleApp(0)
+ wx.InitAllImageHandlers()
+ frmMain = MyFrame(None, -1, "")
+ app.SetTopWindow(frmMain)
+ frmMain.Show()
+ app.MainLoop()
+else:
+ print "TODO: re-enable command line args here"
+
+
diff --git a/trunk/users/stef/pyRepRap/setup.py b/trunk/users/stef/pyRepRap/setup.py
index fd923dfc..a859d175 100644
--- a/trunk/users/stef/pyRepRap/setup.py
+++ b/trunk/users/stef/pyRepRap/setup.py
@@ -9,5 +9,8 @@ setup(
author_email='greenarrow@users.sourceforge.net',
description='Python library to control RepRap firmware using the SNAP protocol.',
packages=['reprap'],
- scripts=['scripts/rrplotdxf', 'scripts/reprapcontrol', 'scripts/rrplotgerber']
+ scripts=['scripts/reprapcontrol', 'scripts/reprapplot'],
+ data_files = [( 'share/reprap/icons', ['reprap/graphics/reprap.png', 'reprap/graphics/connect_established.png', 'reprap/graphics/media-playback-stop.png', 'reprap/graphics/connect_no.png', 'reprap/graphics/go-home.png', 'reprap/graphics/document-open.png', 'reprap/graphics/media-playback-start.png'] )]
)
+
+