How to fix ALDialog Python Script NAOqi Error - python

I am trying to use ALDialog module to have a virtual conversation with the Choregraphe simulated NAO6 robot. I have the below script:
import qi
import argparse
import sys
def main(session):
"""
This example uses ALDialog methods.
It's a short dialog session with two topics.
"""
# Getting the service ALDialog
ALDialog = session.service("ALDialog")
ALDialog.setLanguage("English")
# writing topics' qichat code as text strings (end-of-line characters are important!)
topic_content_1 = ('topic: ~example_topic_content()\n'
'language: enu\n'
'concept:(food) [fruits chicken beef eggs]\n'
'u: (I [want "would like"] {some} _~food) Sure! You must really like $1 .\n'
'u: (how are you today) Hello human, I am fine thank you and you?\n'
'u: (Good morning Nao did you sleep well) No damn! You forgot to switch me off!\n'
'u: ([e:FrontTactilTouched e:MiddleTactilTouched e:RearTactilTouched]) You touched my head!\n')
topic_content_2 = ('topic: ~dummy_topic()\n'
'language: enu\n'
'u:(test) [a b "c d" "e f g"]\n')
# Loading the topics directly as text strings
topic_name_1 = ALDialog.loadTopicContent(topic_content_1)
topic_name_2 = ALDialog.loadTopicContent(topic_content_2)
# Activating the loaded topics
ALDialog.activateTopic(topic_name_1)
ALDialog.activateTopic(topic_name_2)
# Starting the dialog engine - we need to type an arbitrary string as the identifier
# We subscribe only ONCE, regardless of the number of topics we have activated
ALDialog.subscribe('my_dialog_example')
try:
raw_input("\nSpeak to the robot using rules from both the activated topics. Press Enter when finished:")
finally:
# stopping the dialog engine
ALDialog.unsubscribe('my_dialog_example')
# Deactivating all topics
ALDialog.deactivateTopic(topic_name_1)
ALDialog.deactivateTopic(topic_name_2)
# now that the dialog engine is stopped and there are no more activated topics,
# we can unload all topics and free the associated memory
ALDialog.unloadTopic(topic_name_1)
ALDialog.unloadTopic(topic_name_2)
if __name__ == "__main__":
session = qi.Session()
try:
session.connect("tcp://desktop-6d4cqe5.local:9559")
except RuntimeError:
print ("\nCan't connect to Naoqi at IP desktop-6d4cqe5.local(port 9559).\nPlease check your script's arguments."
" Run with -h option for help.\n")
sys.exit(1)
main(session, "desktop-6d4cqe5.local")
My simulated robot has desktop-6d4cqe5.local as IP address and its NAOqi port is running on 63361. I want to run the dialogs outside of the Choregraphe in a python script and only be able to use the dialog box within the Choregraphe to test it. When I ran the above python file I got:
Traceback (most recent call last):
File "C:\Users\...\Documents\...\choregraphe_codes\Welcome\speak.py", line 6, in <module>
import qi
File "C:\Python27\Lib\site-packages\pynaoqi\lib\qi\__init__.py", line 93
async, PeriodicTask)
^
SyntaxError: invalid syntax
I couldn't figure out the problem as there was not much resources online and the robot's documentations are a bit hard to understand.
Please help, thank you.

You are running the script using a Python version greater than 3.5, that sees async as a keyword, now.
NAOqi only supports Python 2.
Try running your script with python2 explicitly.

Related

Error trying to connect a Python client to AWS IoT becuase of the certificates

Hi I am pretty new in this AWS world, what I am trying to do is connect a python client to the AWS IoT service and publish a message, I am using the SDK python and its example, but I have problems whit the certification process, I already have created the thing, the policies and the certification and I downloaded the files, but in the python program I have no idea if I am writing the path to this files in a correct way,
First I tried writing the whole path of each file and nothing then I tried just putting "certificados\thefile" and nothing .
The error that pops up says the error is the path which precesily I do not how to write it.
Thanks for taking the time and sotty if this question is too basic I am just jumping into this.
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0
import time as t
import json
import AWSIoTPythonSDK.MQTTLib as AWSIoTPyMQTT
# Define ENDPOINT, CLIENT_ID, PATH_TO_CERT, PATH_TO_KEY, PATH_TO_ROOT, MESSAGE, TOPIC, and RANGE
ENDPOINT = "MYENDPOINT"
CLIENT_ID = "testDevice"
PATH_TO_CERT = "certificados/5a7e19a0269abe740ac8b38a1bfdab115d14074eb212167a3ba359c0d237a8c3-certificate.pem.crt"
PATH_TO_KEY = "certificados/5a7e19a0269abe740ac8b38a1bfdab115d14074eb212167a3ba359c0d237a8c3-private.pem.key"
PATH_TO_ROOT = "certificados/AmazonRootCA1.pem"
MESSAGE = "Hello World"
TOPIC = "Prueba/A"
RANGE = 20
myAWSIoTMQTTClient = AWSIoTPyMQTT.AWSIoTMQTTClient(CLIENT_ID)
myAWSIoTMQTTClient.configureEndpoint(ENDPOINT, 8883)
myAWSIoTMQTTClient.configureCredentials(PATH_TO_ROOT, PATH_TO_KEY, PATH_TO_CERT)
myAWSIoTMQTTClient.connect()
print('Begin Publish')
for i in range (RANGE):
data = "{} [{}]".format(MESSAGE, i+1)
message = {"message" : data}
myAWSIoTMQTTClient.publish(TOPIC, json.dumps(message), 1)
print("Published: '" + json.dumps(message) + "' to the topic: " + "'test/testing'")
t.sleep(0.1)
print('Publish End')
myAWSIoTMQTTClient.disconnect()
I have created a directory on my deskopt to store this files, its name is "certificados" and from there I am taking the path but it doesn't work.
OSError: certificados/AmazonRootCA1.pem: No such file or directory
Also I am using VS code to run this application.
The error is pretty clear, it can't find the CA cert file at the path you've given it. The path you've given will be interpreted relative to where the files are executed, which is most likely going to be relative to the python file it's self. If that's not the Desktop then you need to provide the fully qualified path:
So assuming Linux, change the paths to:
PATH_TO_CERT = "/home/user/Desktop/certificados/5a7e19a0269abe740ac8b38a1bfdab115d14074eb212167a3ba359c0d237a8c3-certificate.pem.crt"
PATH_TO_KEY = "/home/user/Desktop/certificados/5a7e19a0269abe740ac8b38a1bfdab115d14074eb212167a3ba359c0d237a8c3-private.pem.key"
PATH_TO_ROOT = "/home/user/Desktop/certificados/AmazonRootCA1.pem"

Building the SeeingWand on Raspberry Pi Zero and have coding issues

This is my first posting, so please forgive any lack of decorum
I am building a SeeingWand as outlined in MagPi issue #71.
I have installed and tested all the HW. Then install the python code, the original; code was python2.7, I have update the code to run under python3, but get a strange error when i run the code:
The system displays that the http module does not have a .client attribute.
The documentation says it does. I have tried .client and .server attributes both give the same error. What am i doing wrong?
I have tried several coding variations and several builds of the raspberry OS (Raspbian) mostly give the same errors
import picamera, http, urllib, base64, json, re
from os import system
from gpiozero import Button
CHANGE {MS_API_KEY} BELOW WITH YOUR MICROSOFT VISION API KEY
ms_api_key = "{MS_API_KEY}"
camera button - this is the BCM number, not the pin number
camera_button = Button(27)
setup camera
camera = picamera.PiCamera()
setup vision API
headers = {
'Content-Type': 'application/octet-stream',
'Ocp-Apim-Subscription-Key': ms_api_key,
}
params = urllib.parse.urlencode({
'visualFeatures': 'Description',
})
loop forever waiting for button press
while True:
camera_button.wait_for_press()
camera.capture('/tmp/image.jpg')
body = open('/tmp/image.jpg', "rb").read()
try:
conn = http.client.HTTPsConnection('westcentralus.api.cognitive.microsoft.com')
conn.request("POST", "/vision/v1.0/analyze?%s"%params, body, headers)
response = conn.getresponse()
analysis=json.loads(response.read())
image_caption = analysis["description"]["captions"][0]["text"].capitalize()
# validate text before system() call; use subprocess in next version
if re.match("^[a-zA-z ]+$", image_caption):
system('espeak -ven+f3 -k5 -s120 "' + image_caption + '"')
else :
system('espeak -ven+f3 -k5 -s120 "i do not know what i just saw"')
conn.close()
except Exception as e:
print (e.args)
The system displays an error stating that the http module does not have a .client attribute.
The documentation says it does. I have tried .client and .server attributes both give the same error. What am i doing wrong?
Expected results are:
when i push button 1 I expect the camera to take a picture
when i push button 2 i expect to access MSFT Azure to identify the picture using AI
the final output is for the Wand to access the audio hat and describe what the Wand is "looking" at.
try adding an import like this:
import http.client
Edit: http is a Python package. Even if the package contains some modules, it does not automatically import those modules when you import the package, unless the __init__.py for that package does so on your behalf. In the case of http, the __init__.py is empty, so you get nothing gratis just for importing the package.

ROS Error. "Error processing request: signal only works in main thread"

I am working with Robot Operating System (ROS) and am attempting to make a server/client where the server will boot up ROS nodes that are specified by the client. To perform the "boot up" I am using roslaunch based on the recommendations found here: http://wiki.ros.org/roslaunch/API%20Usage
I can run the roscore in a window and then I can run the server which boots up fine. However, as soon as I try to send the node names I want to boot up via the client, I get the following error:
"Error processing request: signal only works in main thread"
It then points to a bunch of files in various areas that I have not yet tracked down.
I have tried using a simple roslaunch call on each of the launch files I made individually for the nodes I want to launch (in this case turtlesim_node and turtle_teleop_key) and they boot up fine and work by just running roslaunch [package] turtlesim_launch.launch, etc.
Below is the code for my server:
#!/usr/bin/env python
#Filename: primary_server.py
import rospy
import roslaunch
from robot_man.srv import *
class StartUpServer(object):
def __init__(self):
self._nodes = []
def handle_startup(self, names):
self._temp = names.nodes.split(",") #This reades in the
# information from the srv file sent by the client and
# separates each node/package pair
#This loop separates the input from pairs of 2 corresponding
# to the package and node names the user inputs
for i in range(len(self._temp)):
self._nodes.append(self._temp[i].split())
#This loop will launch each node that the user has specified
for package, executable in self._nodes:
print('package is: {0}, executable is: {1}'.format(package, executable))
node = roslaunch.core.Node(package, executable)
launch = roslaunch.scriptapi.ROSLaunch()
launch.start()
process = launch.launch(node)
print('running node: %s'%executable)
return StartUpResponse(self._nodes) #I will change this later
if __name__ == '__main__':
rospy.init_node('startup_node')
server = StartUpServer()
rospy.Service('startup', StartUp, server.handle_startup)
print('The servers are up and running')
rospy.spin()
Here is the code for my client:
#!/usr/bin/env python
#Filename: primary_client_startup.py
import rospy
from robot_man.srv import *
def main(nodes):
rospy.wait_for_service('startup')
proxy = rospy.ServiceProxy('startup', StartUp)
response = proxy(nodes)
return response
if __name__ == '__main__':
nodes = input('Please enter the node packages followed by \
node names separated by spaces. \n To activate multiple nodes \
separate entries with a comma > ')
main(nodes)
Here is my srv file:
#This should be a string of space/comma separated values
string nodes
---
#This should return "success" if node/s start up successfully, else "fail"
string status
And finally, here are the two launch files I have made to launch the turtle simulator:
turtlesim_launch.launch
<launch>
<node name="turtlesim_node" pkg="turtlesim" type="turtlesim_node" />
</launch>
turtle_teleop_launch.launch
<launch>
<node name="turtle_teleop_key" pkg="turtlesim" type="turtle_teleop_key" />
</launch>
I have done a bit of google searching and found no similar problems for ROS (though there are some similar errors for Django and the like but they don't relate).
I appreciate the help!
P.S. It is worth noting that I make it to line 34 when the error occurs (process = launch.launch(node)).
actually that is mentioned in the documentation
You're not calling init_node() from the Python Main thread. Python only allows signals to be registered from the Main thread.
Look here rospyOverviewInitialization and Shutdown
A solution that works (but is quite dirty) is to remove the signal handler registration function:
def dummy_function(): pass
roslaunch.pmon._init_signal_handlers = dummy_function
This way you'll lose the ability to kill the node with CTRL+C, but at least you can start it.
I believe the problem is that you are trying to launch a node in a callback, which as user3732793 says isn't allowed.
If you use append to Queue (or just a list) in the callback, then instead of just rospy.spin() check for items in the queue and then launch if they are there. I believe it will work.
Here is an example

ZEO ZODB database - run locally not working

I tried looking at the documentation for running ZEO on a ZODB database, but it isn't working how they say it should.
I can get a regular ZODB running fine, but I would like to make the database accessible by several processes for a program, so I am trying to get ZEO to work.
I created this script in a folder with a subfolder zeo, which will hold the "database.fs" files created by the make_server function in a different parallel process:
CODE:
from ZEO import ClientStorage
import ZODB
import ZODB.config
import os, time, site, subprocess, multiprocessing
# make the server in for the database in a separate process with windows command
def make_server():
runzeo_path = site.getsitepackages()[0] + "\Lib\site-packages\zeo-4.0.0-py2.7.egg\ZEO\\runzeo.py"
filestorage_path = os.getcwd() + '\zeo\database.fs'
subprocess.call(["python", runzeo_path, "-a", "127.0.0.1:9100", "-f" , filestorage_path])
if __name__ == "__main__":
server_process = multiprocessing.Process(target = make_server)
server_process.start()
time.sleep(5)
storage = ClientStorage.ClientStorage(('localhost', 9100), wait=False)
db = ZODB.DB(storage)
connection = db.open()
root = connection.root()
the program will just block at the ClientStorage line if the wait=False is not given.
If the wait=False is given it produces this error:
Error Message:
Traceback (most recent call last):
File "C:\Users\cbrown\Google Drive\EclipseWorkspace\NewSpectro - v1\20131202\2 - database\zeo.py", line 17, in <module>
db = ZODB.DB(storage)
File "C:\Python27\lib\site-packages\zodb-4.0.0-py2.7.egg\ZODB\DB.py", line 443, in __init__
temp_storage.load(z64, '')
File "C:\Python27\lib\site-packages\zeo-4.0.0-py2.7.egg\ZEO\ClientStorage.py", line 841, in load
data, tid = self._server.loadEx(oid)
File "C:\Python27\lib\site-packages\zeo-4.0.0-py2.7.egg\ZEO\ClientStorage.py", line 88, in __getattr__
raise ClientDisconnected()
ClientDisconnected
Here is the output from the cmd prompt for my process which runs a server:
------
2013-12-06T21:07:27 INFO ZEO.runzeo (7460) opening storage '1' using FileStorage
------
2013-12-06T21:07:27 WARNING ZODB.FileStorage Ignoring index for C:\Users\cab0008
\Google Drive\EclipseWorkspace\NewSpectro - v1\20131202\2 - database\zeo\databas
e.fs
------
2013-12-06T21:07:27 INFO ZEO.StorageServer StorageServer created RW with storage
s: 1:RW:C:\Users\cab0008\Google Drive\EclipseWorkspace\NewSpectro - v1\20131202\
2 - database\zeo\database.fs
------
2013-12-06T21:07:27 INFO ZEO.zrpc (7460) listening on ('127.0.0.1', 9100)
What could I be doing wrong? I just want this to work locally right now so there shouldn't be any need for fancy web stuff.
You should use proper process management and simplify your life. You likely want to look into supervisor, which can be responsible for running/starting/stopping your application and ZEO.
Otherwise, you need to look at the double-fork trick to daemonize ZEO -- but why bother when a process management tool like supervisor does this for you.
If you are savvy with relational database administration, and already have a relational database at your disposal -- you can also consider RelStorage as a very good ZODB (low-level) storage backend.
In Windows you should use double \ instead of a single \ in the paths. Easy and portable way to accomplish this is to use os.path.join() function, eg. os.path.join('os.getcwd()', 'zeo', 'database.fs'). Otherwise a similar code worked ok for me.
Had same error on Windows , on Linux everything OK ...
your code is ok , to make this to work change following
C:\Python33\Lib\site-packages\ZEO-4.0.0-py3.3.egg\ZEO\zrpc\trigger.py ln:235
self.trigger.send(b'x')
C:\Python33\Lib\site-packages\ZEO-4.0.0-py3.3.egg\ZEO\zrpc\client.py ln:458:459 - comment them
here is those lines:
if socktype != socket.SOCK_STREAM:
continue

How can I set the rating of a song playing in Rhythmbox 2.96?

I am trying to create a Python plugin which will set the rating of the currently playing song in Rhythmbox 2.96. It appears that Rhythmbox 2.96 doesn't let you use the API (Python modules) to set the rating of a song anymore; player related actions have been dropped in favor of MPRIS.
I then tried looking at using dbus with MPRIS but MPRIS doesn't have a spec for setting the rating of a song either. After a lot of digging, I found this sample in the Rhythmbox codebase and adapted it into a test script.
It works, but the SetEntryProperties method is causing Rhythmbox to freeze for about 30 seconds. Here is the Python script.
Instructions:
Copy the code into a file called rate.py
Start rhythmbox from a terminal using
rhythmbox -D rate
In Rhythmbox, enable the Python Console from the plugins
Start the Python Console and run
execfile('/path/to/rate.py')
You will see the print output in the terminal and Rhythmbox freezes for about 20-30 seconds.
# rhythmbox -D rate
# Rhythmbox: Edit > Plugins > Python Console enabled
# Play a song
# Open Rhythmbox Python Console
# execfile('/path/to/rate.py')
import sys
import rb
from gi.repository import Gtk, Gdk
def rateThread(rating):
try:
currentSongURI = shell.props.shell_player.get_playing_entry().get_playback_uri()
print "Setting rating for " + currentSongURI
from gi.repository import GLib, Gio
bus_type = Gio.BusType.SESSION
flags = 0
iface_info = None
print "Get Proxy"
proxy = Gio.DBusProxy.new_for_bus_sync(bus_type, flags, iface_info,
"org.gnome.Rhythmbox3",
"/org/gnome/Rhythmbox3/RhythmDB",
"org.gnome.Rhythmbox3.RhythmDB", None)
print "Got proxy"
rating = float(rating)
vrating = GLib.Variant("d", rating)
print "SetEntryProperties"
proxy.SetEntryProperties("(sa{sv})", currentSongURI, {"rating": vrating})
print "Done"
except:
print sys.exc_info()
return False
def rate():
if shell.props.shell_player.get_playing_entry():
Gdk.threads_add_idle(100, rateThread, 3)
rate()
The exception that gets printed is:
Desktop/test2.py:41: (<class 'gi._glib.GError'>, GError('Timeout was
reached',), <traceback object at 0x913e554>)
My knowledge of Python/dbus is limited, so I don't understand why that error is occurring. I'd appreciate any help with it.
Also, if you know of a better way of setting the rating of a song in Rhythmbox through code, it would be welcome too!
I am using Ubuntu 12.04, if it makes a difference.
Setting the Rating within a plugin
Rhythmbox 2.9x does provide an API to set the Rating - there is no need to call via dbus unless you are using an external program such as the Rhythmbox Tray Icon.
Ratings are held as double type values in its internal database. Using a RhythmDBEntry you can obtain the Rating with
rating = entry.get_double(RB.RhythmDBPropType.RATING)
To set the rating you'll need the RhythmDB entry_set function:
db=self.shell.props.db
db.entry_set(entry, RB.RhythmDBPropType.RATING, rating)
Example code for getting and setting ratings can be found in the CoverArt Browser plugin (coverart_album.py)
The Rhythmbox Tray Icon plugin on github does manage to set the song rating, but it does it from outside the Rhythmbox execution environment.
From here:
def SetSongRating(self, rating):
"""
Sets the current song rating in Rhythmbox.
"""
try:
currentSongURI = self.GetSongURI()
if currentSongURI:
busType = Gio.BusType.SESSION
flags = 0
ratingInterface = None
proxy = Gio.DBusProxy.new_for_bus_sync(busType, flags, ratingInterface,
"org.gnome.Rhythmbox3",
"/org/gnome/Rhythmbox3/RhythmDB",
"org.gnome.Rhythmbox3.RhythmDB", None)
variantRating = GLib.Variant("d", float(rating))
proxy.SetEntryProperties("(sa{sv})", currentSongURI, {"rating": variantRating})
except:
print "Failed to set a rating"
If I tried to run that code from directly inside a Rhythmbox plugin, it would freeze again. However, running it from outside the Rhythmbox environment worked perfectly fine. I found this good enough so I'll mark this as the answer.

Categories

Resources