25.04.2009Fellow and Friend
24.04.2009Using zeroc’s Icestorm in Python
CORBA is great, but ICE is great and cool, which makes it awesome
But good examples on using the publish/subscribe channel system of Icestorm in python are hard to find. Here is what I did:
config.icebox
1 2 | IceBox.ServiceManager.Endpoints=tcp -p 9999 IceBox.Service.IceStorm=IceStormService,32:createIceStorm --Ice.Config=config.icestorm |
config.icestorm
1 2 3 4 5 | IceStorm.InstanceName=Simple IceStorm.TopicManager.Proxy=Simple/TopicManager:default -p 10000 IceStorm.TopicManager.Endpoints=tcp -p 10000 IceStorm.Publish.Endpoints=tcp Freeze.DbEnv.IceStorm.DbHome=db |
start icebox with: icebox –Ice.Config=config.icebox
Simple.ice
1 2 3 4 5 6 7 8 9 | module Simple { struct Message { string content; }; interface Processor { void process (Message m); }; }; |
subscriber.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #!/usr/bin/python # Subscribe to the storm (channel) 'MyTopic' # and offer an instance of 'ProcessorI' as remote-object. import sys, Ice, IceStorm Ice.loadSlice('Simple.ice', ['-I', '/opt/Ice-3.2.1/bin/slice'])# can also be /usr/share/slice import Simple # Implementation of the Processor class (defined in the ice file) class ProcessorImpl (Simple.Processor): def process (self, message, curr): print message.content class Subscriber (Ice.Application): def run (self, argv): self.shutdownOnInterrupt() # Get the TopicManager. prx = self.communicator().stringToProxy('Simple/TopicManager:tcp -p 10000') topicManagerPrx = IceStorm.TopicManagerPrx.checkedCast(prx) # Create the remote object oa = self.communicator().createObjectAdapterWithEndpoints('SubscriberOA', 'default') processorPrx = oa.addWithUUID(ProcessorImpl()) # Get the topic from the manager. try: topicPrx = topicManagerPrx.retrieve('MyTopic') except IceStorm.NoSuchTopic: topicPrx = topicManagerPrx.create('MyTopic') # Subscribe the remote object to the storm (channel) topicPrx.subscribeAndGetPublisher(None, processorPrx) oa.activate() self.communicator().waitForShutdown() topicPrx.unsubscribe(processorPrx) return 0 Subscriber().main(sys.argv) |
publisher.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #!/usr/bin/python # Subscribe to the storm (channel) 'MyTopic' # and call the remote-objects function 'process()' import sys, Ice, IceStorm Ice.loadSlice('Simple.ice', ['-I', '/opt/Ice-3.2.1/bin/slice'])# can also be /usr/share/slice import Simple from time import sleep class Publisher (Ice.Application): def run (self, argv): # Get the TopicManager. prx = self.communicator().stringToProxy('Simple/TopicManager:tcp -p 10000') topicManagerPrx = IceStorm.TopicManagerPrx.checkedCast(prx) # Get the topic from the manager. try: topicPrx = topicManagerPrx.retrieve('MyTopic') except IceStorm.NoSuchTopic: topicPrx = topicManagerPrx.create('MyTopic') # Proxy of the remote object pub = topicPrx.getPublisher() processorPrx = Simple.ProcessorPrx.uncheckedCast(pub) # Publish some messages on the remote objects function 'process()'. m = Simple.Message('Hello') processorPrx.process(m) sleep(2) m = Simple.Message('World!') processorPrx.process(m) return 0 Publisher().main(sys.argv) |
You can download the whole stuff here.
To run everything, open three terminals. Launch icebox (icebox –Ice.Config=config.icebox), start the subscriber (python subscriber.py) and finally start the publisher (python publisher.py) as often, as you would like to shout your “Hello World!” over the storm-channels
Hope that helps.
Cheers Gecko
21.04.2009Letztens in Bremen
21.04.2009Driving NXT with Python, using Bluetooth
I had quite a hard time, setting up my NXT the way I wanted. The basic Idea is to tele-operate the robot, using its bluetooth connection under Linux. Since the robot is running under LeJOS I thought it to be best to start off with a bluetooth socket client/server thing in java.
Server:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | // compile with: nxjc BTReceive.java // uploade with: sudo /home/gecko/Programme/lejos_nxj/bin/nxj -r BTReceive import lejos.nxt.*; import lejos.nxt.comm.*; import lejos.nxt.socket.*; import java.io.*; public class BTReceive { public static void main(String [] args) throws Exception { String connected = "Connected"; String waiting = "Waiting..."; String closing = "Closing..."; while (true) { LCD.drawString(waiting,0,0); NXTConnection connection = Bluetooth.waitForConnection(); LCD.clear(); LCD.drawString(connected,0,0); DataInputStream dis = connection.openDataInputStream(); DataOutputStream dos = connection.openDataOutputStream(); String s = dis.readLine(); LCD.drawString(s,0,4); dos.writeChars(s); dos.flush(); Thread.sleep(5000); dis.close(); dos.close(); LCD.clear(); LCD.drawString(closing,0,0); connection.close(); } } } |
Client:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | import lejos.pc.comm.*; import java.io.*; public class BTSend { private static char END_CHAR = '\n'; public static void main(String[] args) throws Exception { NXTComm nxtComm = NXTCommFactory.createNXTComm(NXTCommFactory.BLUETOOTH); // find the nearest NXT NXTInfo[] nxtInfo = nxtComm.search("NXT", NXTCommFactory.BLUETOOTH); if (nxtInfo.length == 0) { System.out.println("No NXT Found"); System.exit(1); } System.out.println("Adr: " + nxtInfo[0].btDeviceAddress); System.out.println("Connecting to " + nxtInfo[0].btResourceString); boolean opened = nxtComm.open(nxtInfo[0]); if (!opened) { System.out.println("Failed to open " + nxtInfo[0].name); System.exit(1); } System.out.println("Connected to " + nxtInfo[0].btResourceString); InputStream is = nxtComm.getInputStream(); OutputStream os = nxtComm.getOutputStream(); DataOutputStream dos = new DataOutputStream(os); DataInputStream dis = new DataInputStream(is); try { System.out.println("Sending data"); dos.writeChars("Hello from PC" + END_CHAR); dos.flush(); System.out.println("Sending done"); } catch (IOException ioe) { System.out.println("IO Exception writing bytes"); System.out.println(" ::" + ioe.toString()); } catch (Exception e) { System.out.println(" ::" + e.toString()); } StringBuffer strb = new StringBuffer(); try { char c = dis.readChar(); while(c != END_CHAR) { strb.append(c); c = dis.readChar(); } } catch (IOException ioe) { System.out.println("IO Exception writing received bytes"); System.out.println(" ::" + ioe.toString()); } catch (Exception e) { System.out.println(" ::" + e.toString()); } System.out.println("Received data: " + strb.toString()); try { dis.close(); nxtComm.close(); } catch (IOException ioe) { System.out.println("IOException closing connection"); } } } |
That worked pretty well… But once I tried to use the server from within Python … nothing!
To cut a long Path short, if you are using NXT Python, you don’t need a server running on the NXT. All you need to do is to connect to the brick, hand the connection to the sensor/actuator you want to use and start coding, like you’re working on the robot itself… Maybe that is obvious to some people, but to me it wasn’t. So if there is someone else like me out there, desperately in love with python, trying to run the NXT… here’s how my stuff worked. Hope that helps.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | #!/usr/bin/env python import nxt.bluesock from nxt.sensor import * from nxt.motor import * #import nxt.locator # enable bluetooth connection socket = nxt.bluesock.BlueSock("00:16:53:07:1D:00") #socket = nxt.locator.find_one_brick() if socket: brick = socket.connect() print "connected" else: print "couldn't get bluetooth connection" exit(0) # initialize robot # BUMPERS touch_left = TouchSensor(brick, PORT_2) touch_right = TouchSensor(brick, PORT_1) # MOTORS m_left = Motor(brick, PORT_B) m_right = Motor(brick, PORT_A) # ULTRA SONIC ultra_left = UltrasonicSensor(brick, PORT_4) ultra_right = UltrasonicSensor(brick, PORT_3) # set motor speed def set_speed(motor, speed, caps=70): # limit motor output to caps (default = 70) if(speed >= caps): speed = caps elif(speed <= -caps): speed = -caps # set speed motor.power = speed motor.mode = MODE_MOTOR_ON motor.run_state = RUN_STATE_RUNNING motor.set_output_state() # get touch sensor state # returns true or false def get_touch(touch_sensor): return touch_sensor.get_sample() # get sonar sensor values (0-255) def getSonarInfo(sonar): return sonar.get_single_shot_measurement() |
21.04.2009Hello world!
Hello World!
Hello Gecko!



