user2757771
user2757771

Reputation: 188

Communicating between multiple python programs running in parallel

Here's a summary of my setup:

The end goal is for a UI made in C# to initiate an automated test cycle for the CNC to run in. In the python program there is a Cnc object that stores the devices current position and contains methods to position it to a certain place.

The problem is if i run a new script every time i want to move the CNC, I have to re initialize the Cnc instance and it will forget it's position. So I'm wondering if I can have one master program running that contains the one and only Cnc instance, then when the remote machine wants to tell the CNC to move it can run a different script with argz for the new position python action.py x y z. This script could then communicate to the master program to call the move method to the appropriate location without ever having to re-construct a new Cnc object. Then ideally the master program would indicate when the motion is completed and send back a message to the "action" script, that script would output something to tell the remote system that the action is completed, then it would exit, ready to be called again with new argz.

In the end the remote system is highly abstracted from any of the working and just needs to start running the master, then run the move script with argz any time it wants to perform a motion.

Note: My other idea was to just save a text file with the current position then always re initialize the instance with the info in the file.

EDIT: SOLVED... sort of

handler.py

The handler will continuously read from a text file named input.txt looking for a new integer. If received it will update a text file named output.txt to read '0', then do some action with the input (i.e move a cnc) then write the value '1' to output.txt.

from time import sleep
cur_pos=0

while True:
    with open("input.txt","r") as f:
        pos=f.readline()
    try:
        if pos=='':
            pass
        else:
            pos=int(pos)
    except:
        print pos
        print("exititng...")
        exit()

    if cur_pos==pos or pos=='':
        #suggestion from @Todd W to sleep before next read
        sleep(0.3)
        pass
    else:
        print("Current pos: {0:d}, New pos: {1:d}".format(cur_pos,pos))
        print("Updating...")
        with open("output.txt","w") as f:
            f.write("0")
        #do some computation with the data
        sleep(2)
        cur_pos=pos
        print("Current pos: {0:d}".format(cur_pos))
        with open("output.txt","w") as f:
            f.write("1")

pass_action.py

The action passer will accept a command line argument, write it to input.txt, then wait for output.txt to read '1', after which it will print done and exit.

import sys
from time import sleep
newpos=sys.argv[1]
with open("input.txt","w") as f:
    f.write(newpos)

while True:
    sleep(0.1)
    with open("output.txt","r") as f:
        if f.readline()=='1':
            break

sys.stdout.write("done")

Upvotes: 0

Views: 1095

Answers (3)

eatmeimadanish
eatmeimadanish

Reputation: 3907

Your better bet is to combine gevent with GIPC https://gehrcke.de/gipc/

This allows for asynchronous calls to a stack, and communication between separate processes.

Upvotes: 1

Todd W
Todd W

Reputation: 397

If you really want to be dead simple, have your "main" CNC script read a designated directory on the file system looking for a text file that has one or more commands. If multiple files are there, take the earliest file and execute the command(s). Then delete the file (or move it to another directory) and get the next file. If there's no file, sleep for a few seconds and check again. Repeat ad nauseam. Then your C# app just has to write a command file to the correct directory.

Upvotes: 2

Todd W
Todd W

Reputation: 397

One possible approach might just be to make your main python script a webapp using something like Flask or Bottle. Your app initializes the cnc, then waits for HTTP input, maybe on an endpoint like 'move'. Your C# app then just sends a REST request (HTTP) to move like {'coordinates': [10,15]} and your app acts on it.

Upvotes: 2

Related Questions