from david beazley paper(https://www.dabeaz.com/usenix2009/concurrent/Concurrent.pdf, pg62), i am trying to run codes :
# channel.py
import pickle
class Channel(object):
def __init__(self,out_f,in_f):
self.out_f = out_f
self.in_f = in_f
def send(self,item):
pickle.dump(item,self.out_f)
self.out_f.flush()
def recv(self):
return pickle.load(self.in_f)
# child.py
import channel
import sys
ch = channel.Channel(sys.stdout,sys.stdin)
while True:
item = ch.recv()
ch.send(("child",item))
# parent.py
import channel
import subprocess
p = subprocess.Popen(['python','child.py'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
ch = channel.Channel(p.stdin,p.stdout)
• Using the child worker
ch.send("Hello World")
Hello World
When I try this code, I got this error
Traceback (most recent call last):
File "child.py", line 6, in <module>
item = ch.recv()
File "C:\Users\bluesky\backtest\channel.py", line 16, in recv
return pickle.load(self.in_f)
TypeError: a bytes-like object is required, not 'str'
what i am trying to get is that sending my data to child and get back processed data to parent process, is there any way to fix it
Related
I am trying to follow a ROS2 testing tutorial which tests a topic listener to understand how ROS2 testing works. Here is a screenshot of the related code at 21:15
I have a node target_control_node which subscribes the topic turtle1/pose and then move the turtle to a new random pose.
import math
import random
import rclpy
from geometry_msgs.msg import Twist
from rclpy.node import Node
from turtlesim.msg import Pose
class TargetControlNode(Node):
def __init__(self):
super().__init__("target_control_node")
self.get_logger().info("target_control_node")
self._target_pose = None
self._cmd_vel_publisher = self.create_publisher(Twist, "turtle1/cmd_vel", 10)
self.create_subscription(Pose, "turtle1/pose", self.subscribe_target_pose, 10)
self.create_timer(1.0, self.control_loop)
def subscribe_target_pose(self, msg):
self._target_pose = msg
def control_loop(self):
if self._target_pose is None:
return
target_x = random.uniform(0.0, 10.0)
target_y = random.uniform(0.0, 10.0)
dist_x = target_x - self._target_pose.x
dist_y = target_y - self._target_pose.y
distance = math.sqrt(dist_x**2 + dist_y**2)
msg = Twist()
# position
msg.linear.x = 1.0 * distance
# orientation
goal_theta = math.atan2(dist_y, dist_x)
diff = goal_theta - self._target_pose.theta
if diff > math.pi:
diff -= 2 * math.pi
elif diff < -math.pi:
diff += 2 * math.pi
msg.angular.z = 2 * diff
self._cmd_vel_publisher.publish(msg)
def main(args=None):
rclpy.init(args=args)
node = TargetControlNode()
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
if __name__ == "__main__":
main()
I am trying to write a simple test for the subscription part based on the tutorial above to understand how it works.
Here is my initial test code. Note inside I am using expected_output=str(msg), however, it is wrong, and I am not sure what to put there.
import pathlib
import random
import sys
import time
import unittest
import uuid
import launch
import launch_ros
import launch_testing
import pytest
import rclpy
import std_msgs.msg
from geometry_msgs.msg import Twist
from turtlesim.msg import Pose
#pytest.mark.rostest
def generate_test_description():
src_path = pathlib.Path(__file__).parent.parent
target_control_node = launch_ros.actions.Node(
executable=sys.executable,
arguments=[src_path.joinpath("turtle_robot/target_control_node.py").as_posix()],
additional_env={"PYTHONUNBUFFERED": "1"},
)
return (
launch.LaunchDescription(
[
target_control_node,
launch_testing.actions.ReadyToTest(),
]
),
{
"target_control_node": target_control_node,
},
)
class TestTargetControlNodeLink(unittest.TestCase):
#classmethod
def setUpClass(cls):
rclpy.init()
#classmethod
def tearDownClass(cls):
rclpy.shutdown()
def setUp(self):
self.node = rclpy.create_node("target_control_test_node")
def tearDown(self):
self.node.destroy_node()
def test_target_control_node(self, target_control_node, proc_output):
pose_pub = self.node.create_publisher(Pose, "turtle1/pose", 10)
try:
msg = Pose()
msg.x = random.uniform(0.0, 10.0)
msg.y = random.uniform(0.0, 10.0)
msg.theta = 0.0
msg.linear_velocity = 0.0
msg.angular_velocity = 0.0
pose_pub.publish(msg)
success = proc_output.waitFor(
# `str(msg)` is wrong, however, I am not sure what to put here.
expected_output=str(msg), process=target_control_node, timeout=1.0
)
assert success
finally:
self.node.destroy_publisher(pose_pub)
When I run launch_test src/turtle_robot/test/test_target_control_node.py, it only prints this without telling me what is actual output:
[INFO] [launch]: All log files can be found below /home/parallels/.ros/log/2023-01-02-16-37-27-631032-ubuntu-linux-22-04-desktop-1439830
[INFO] [launch]: Default logging verbosity is set to INFO
test_target_control_node (test_target_control_node.TestTargetControlNodeLink) ... [INFO] [python3-1]: process started with pid [1439833]
[python3-1] [INFO] [1672706247.877402445] [target_control_node]: target_control_node
FAIL
======================================================================
FAIL: test_target_control_node (test_target_control_node.TestTargetControlNodeLink)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/my-ros/src/turtle_robot/test/test_target_control_node.py", line 91, in test_target_control_node
assert success
AssertionError
----------------------------------------------------------------------
Ran 1 test in 1.061s
FAILED (failures=1)
[INFO] [python3-1]: sending signal 'SIGINT' to process[python3-1]
[python3-1] Traceback (most recent call last):
[python3-1] File "/my-ros/src/turtle_robot/turtle_robot/target_control_node.py", line 59, in <module>
[python3-1] main()
[python3-1] File "/my-ros/src/turtle_robot/turtle_robot/target_control_node.py", line 53, in main
[python3-1] rclpy.spin(node)
[python3-1] File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/__init__.py", line 222, in spin
[python3-1] executor.spin_once()
[python3-1] File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/executors.py", line 705, in spin_once
[python3-1] handler, entity, node = self.wait_for_ready_callbacks(timeout_sec=timeout_sec)
[python3-1] File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/executors.py", line 691, in wait_for_ready_callbacks
[python3-1] return next(self._cb_iter)
[python3-1] File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/executors.py", line 588, in _wait_for_ready_callbacks
[python3-1] wait_set.wait(timeout_nsec)
[python3-1] KeyboardInterrupt
[ERROR] [python3-1]: process has died [pid 1439833, exit code -2, cmd '/usr/bin/python3 /my-ros/src/turtle_robot/turtle_robot/target_control_node.py --ros-args'].
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
I checked the source code of waitFor, but still no clue.
Is there a way to print the actual output so that I can give correct expected_output? Thanks!
To answer your question(and give some more general tips): You can always print out the msg inside the node. That said, the reason you're getting an error is because msg is a ros message type, meaning it's an object. So by doing str(msg) your expected output will be something like <object of type Pose at (some_address)>; and not the actual message values. Also since it appears you're just testing a subscriber, it doesn't usually make sense to have a unit test that's expecting stdout. I would also note that you're publishing a message before actually waiting for the result, this should always fail. The reason is because by the time your subscriber is started, the message has already been published and is gone.
Finally, you shouldn't have a publisher included in any unit tests. It adds an extra dependency and since it's a prepackaged transport layer testing if it works is irrelevant. Instead to fix your problem you should simply be calling the individual methods of your node directly. Basically import the script, instantiate the object, and don't try to deal with the whole node lifecycle.
Edit based on comments
Looking at your subscriber code, you'll need to actually print something out. Unfortunately because it's not a std_msg(i.e. it has more fields than just .data) you'll need to decide how you want to go about confirming the data is right. You could simply look at one field or all of them in order. For example you might have in your test:
success = proc_output.waitFor(
expected_output=str(msg.x),
process=target_control_node, timeout=1.0)
And in your control node:
def subscribe_target_pose(self, msg):
self._target_pose = msg
print(msg.x)
That said, this IO handling method doesn't seem like the best to me. Mainly because it relies on stdout which isn't something you always want.
i am trying to add a progressbar to my script but i couldn't succeed because i think it is multi-threaded or maybe it should be added in a separate thread . i found plenty of solutions in stackoverflow , for example tqdm library but i couldn't implement it , also i think i have a confusion where exactly i have to implement the progress bar code to make it works.
this is my code :
# -*- coding: utf-8 -*
from __future__ import unicode_literals
# !/usr/bin/python
import codecs
from multiprocessing.dummy import Pool
start_raw = "myfile"
threads = 10
with codecs.open(start_raw, mode='r', encoding='ascii', errors='ignore') as f:
lists = f.read().splitlines()
lists = list((lists))
def myfunction(x):
try:
print x
except:
pass
def Main():
try:
pp = Pool(int(threads))
pr = pp.map(myfunction, lists)
except:
pass
if __name__ == '__main__':
Main()
i have tried this solution
https://stackoverflow.com/a/45276885/9746396 :
# -*- coding: utf-8 -*
from __future__ import unicode_literals
# !/usr/bin/python
import codecs
from multiprocessing.dummy import Pool
import tqdm
start_raw = "myfile"
threads = 1
with codecs.open(start_raw, mode='r', encoding='ascii', errors='ignore') as f:
lists = f.read().splitlines()
lists = list((lists))
def myfunction(x):
try:
print (x)
except:
pass
def Main():
try:
pp = Pool(int(threads))
pr = pp.map(myfunction, lists)
except:
pass
if __name__ == '__main__':
with Pool(2) as p:
r = list(tqdm.tqdm(p.imap(Main(), range(30)), total=30))
but code does not run and i get exception (TypeError: 'NoneType' object is not callable)
0%| | 0/30 [00:00<?, ?it/s]Traceback (most recent call last):
File "file.py", line 35, in <module>
r = list(tqdm.tqdm(p.imap(Main(), range(30)), total=30))
File "C:\mypath\Python\Python38-32\lib\site-packages\tqdm\std.py", line 1118, in __iter__
for obj in iterable:
File "C:\mypath\Python\Python38-32\lib\multiprocessing\pool.py", line 865, in next
raise value
File "C:\mypath\Python\Python38-32\lib\multiprocessing\pool.py", line 125, in worker
result = (True, func(*args, **kwds))
TypeError: 'NoneType' object is not callable
0%| | 0/30 [00:00<?, ?it/s]
I presume you wanted to pass myfunction instead of Main to imap, consistently with the first example.
When you pass Main() to p.imap in r = list(tqdm.tqdm(p.imap(Main(), range(30)), total=30)), Python calls executes Main method and passes the return value as the first argument to imap.
You should remove the parentheses after Main as: p.imap in r = list(tqdm.tqdm(p.imap(Main, range(30)), total=30)).
This program is supposed to emit sound based on a CSV file.
There is a frequency range in the dataset of 37-32677. In the beginning I didn't add this in and got this same error message. I tried adding in this range and I am still getting the same error.
import winsound
import csv
winsound.Beep(261,100)
def preload(filename):
file = open(filename)
data = csv.reader(file)
return data
def getNote(sensorVal):
return int(sensorVal * 75)
def setup():
cleanedData = {}
notes = []
data = preload("data1.csv")
for row in data(range(36,32677)):
print(row)
if row[1] != "trial number":
sensorVal = float(row[4])
channel = int(row[7])
if channel not in cleanedData:
cleanedData[channel] = []
cleanedData[channel].append({"sensorVal":sensorVal})
notes.append(getNote(sensorVal))
return cleanedData,notes
def play(notes,time):
for note in notes:
winsound.Beep(note,time)
data, notes = setup()
play(notes, 200)
Error message:
Traceback (most recent call last):
File "C:/Users/clair/PycharmProjects/winSound/main.py", line 32, in <module>
data, notes = setup()
File "C:/Users/clair/PycharmProjects/winSound/main.py", line 16, in setup
for row in data(range(36,32677)):
TypeError: '_csv.reader' object is not callable
Process finished with exit code 1
I am using the Python pocket sphinx tutorial, according to
https://metakermit.com/2011/python-speech-recognition-helloworld/
(complete code here):
import sys,os
def decodeSpeech(hmmd,lmdir,dictp,wavfile):
"""
Decodes a speech file
"""
try:
import pocketsphinx as ps
import sphinxbase
except:
print """Pocket sphinx and sphixbase is not installed
in your system. Please install it with package manager.
"""
speechRec = ps.Decoder(hmm = hmmd, lm = lmdir, dict = dictp)
wavFile = file(wavfile,'rb')
wavFile.seek(44)
speechRec.decode_raw(wavFile)
result = speechRec.get_hyp()
return result[0]
if __name__ == "__main__":
hmdir = "/usr/share/pocketsphinx/model/hmm/en_US/"
lmd = "/usr/share/pocketsphinx/model/lm/en_US/hub4.5000.DMP"
dictd = "/usr/share/pocketsphinx/model/lm/en_US/cmu07a.dic"
wavfile = sys.argv[1]
recognised = decodeSpeech(hmdir,lmd,dictd,wavfile)
print "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
print recognised
print "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
and when I run it I get the following error message:
Traceback (most recent call last):
File "hello.py", line 30, in <module>
recognised = decodeSpeech(hmdir,lmd,dictd,wavfile)
File "hello.py", line 17, in decodeSpeech
speechRec = ps.Decoder(hmm = hmmd, lm = lmdir, dict = dictp)
TypeError: __init__() got an unexpected keyword argument 'hmm'
Could you help me?
Looking at the pocketsphinx code on GitHub, in decoder_test.py we have an example of how to pass options to Decoder.
So it looks like your tutorial is for an old version and you actually want:
config = ps.Decoder.default_config()
config.set_string('-hmm', hmmd)
config.set_string('-lm', lmdir)
config.set_string('-dict', dictp)
speechRec = ps.Decoder(config)
I have installed gstreamer, gst-plugins-bad and its python bindings.
The following code selects a song from a given directory and plays it.
import pygst
pygst.require("0.10")
import gst
import pygtk
import gtk
import os
class Main:
def __init__(self):
self.pipeline = gst.Pipeline("mypipeline")
self.musicFiles = os.listdir("musicFiles")
self.currentSong = self.musicFiles[0]
self.findFile = gst.element_factory_make("filesrc", "file")
self.findFile.set_property("location", "musicFiles/" + self.currentSong)
self.pipeline.add(self.findFile)
self.mad = gst.element_factory_make("mad", "mad")
self.pipeline.add(self.mad)
self.findFile.link(self.mad)
self.audioconvert = gst.element_factory_make("audioconvert", "convert")
self.pipeline.add(self.audioconvert)
self.mad.link(self.audioconvert)
self.audioresample = gst.element_factory_make("audioresample", "resample")
self.pipeline.add(self.audioresample)
self.audioconvert.link(self.audioresample)
self.getbpm = gst.element_factory_make("bpmdetect", "bpm")
self.pipeline.add(self.getbpm)
self.audioresample.link(self.getbpm)
self.sink = gst.element_factory_make("playsink", "sink")
self.pipeline.add(self.sink)
self.audioresample.link(self.sink)
self.pipeline.set_state(gst.STATE_PLAYING)
start=Main()
gtk.main()
However, when I try to create the bpmdetect element, it gives the following error:
Traceback (most recent call last):
File "/Users/shubhitsingh/Desktop/Stuff/COLLEGE/US/Carnegie Mellon/Fall '12/15-112/Term Project/Practice/gstreamertutorial-1.py", line 49, in <module>
start=Main()
File "/Users/shubhitsingh/Desktop/Stuff/COLLEGE/US/Carnegie Mellon/Fall '12/15-112/Term Project/Practice/gstreamertutorial-1.py", line 37, in __init__
self.getbpm = gst.element_factory_make("bpmdetect", "bpm")
ElementNotFoundError: bpmdetect
Other elements from gst-plugins-bad can be created without problems. Its just the two elements under soundtouch (bpmdetect and pitch) that cannot be created. Help?