i am new to multiprocessing. I am starting a child_process from my parent script. The child_process is a sensor that is sending live data continuesly. Within the child script i am sending that data onto the pipe from where it can be fetched from the parent script whenever needed. I realised that i have a delay in the data. The data i am trying to get is not the live data from the sensor, it data that has been recorded earlier.
Is there any other approach for this to handle live data ?
Function in the child script:
i added a time.sleep(0.1 and it improved the issue a little but its not accurate enough)
def _send_data(self):
time.sleep(1)
offsets = self.calculate_offset()
try:
while 1:
if self._conn:
zeroed_data = self.zero_data(offsets,self.get_data())
status = {
"Status": self._status,
"Timestamp": sR.millis(),
"Temperature": self._temperature,
}
status.update(zeroed_data)
self._conn.send(status)
time.sleep(0.1)
except KeyboardInterrupt:
# ctrl-C abort handling
if self.conn:
self.conn.close()
print('stopped')
def main_bota(child_conn,port):
print('bota started')
bota_sensor_1 = None
try:
bota_sensor_1 = BotaSerialSensor(port,child_conn);
bota_sensor_1.run()
except BotaSerialSensorError as expt:
print('bota failed: ' + expt.message)
except Exception as e:
print(f"An unexpected error occured: {e}")
finally:
if bota_sensor_1 is not None:
bota_sensor_1.close()
sys.exit(1)
Function in the parent script:
def robot_command(selected_tool, path):
"""send commands to robot according to the path.
Args:
selected_tool (np.array): selected tool matrix (4x4)
path (list): List of transformation matrices defining the robots path.
"""
worldToToolStart = sR.getWorldToTool(s, BUFFER_SIZE, selected_tool)
totNumbPos = len(path)
totNumb = 0
for i in range(totNumbPos):
totNumb += 1
toolToNewTarget = path[i]
worldToNewTarget = np.matmul(worldToToolStart, toolToNewTarget)
worldToFlangeCommand = np.matmul(
worldToNewTarget, sR.homInv(selectedTool))
# Formulate the command based on robot mode
if robotMode == 'SmartServo':
poseStringForRobot = sR.make_cmd(
"MovePTPHomRowWiseMinChangeRT", worldToFlangeCommand)
else:
poseStringForRobot = sR.make_cmd(
"MovePTPHomRowWiseMinChange", worldToFlangeCommand)
# Send command to robot
sR.command(s, BUFFER_SIZE, poseStringForRobot)
# get sensor data
sensordata = parent_conn.recv()
# Check status of Bota
#status_bota(sensordata['Status'])
# get robot data dict and combine with sensor data dict
robotdata = fetch_robot_data()
combined_data = {**sensordata, **robotdata}
#append combined_data to global data
data.append(combined_data)
print(i)
print(robotdata["timestamp"])
print(sensordata["Timestamp"])
# Wait until position is reached (can be adjusted...)
sR.delay(delayBetweenPoses)
functions that connect to the sensor and disconnect
def connect_bota(port):
global p,parent_conn
parent_conn, child_conn = Pipe()
p = Process(target=main_bota, args = (child_conn,port))
p.start()
print('process bota started')
def disconnect_bota():
p.terminate()
p.join()
print('process bota stopped')
def main():
config()
name = generate_experiment_name()
print(name)
display_config()
connect_to_robot()
connect_bota(port='COM3')
# generate selected path
path = generate_path(selectedPath_str)
# (go to supportRobot file to adapt initialization parameters (velocities, damping, ...))
sR.initRobot(s, BUFFER_SIZE, robotMode)
print('initRobot')
# Delay for 3s
delay(2)
# Send command to robot
print('send command')
robot_command(selectedTool, path)
# End of operations
print('STOP in 2s')
delay(2)
disconnect_bota()
s.close()
print("STOPPED")
I used Manger() of multiprocessing instead of Pipe()
sender
receiver