Building the SeeingWand on Raspberry Pi Zero and have coding issues - python

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.

Related

Could not load the file : Error when calling a dll in python project

We have a python library(Lets call it TestLibrary), made as a 'whl' file.
We are consuming that library in another python project(Main Project)(flask based).
In test library, we are calling a dll(C#, Net standard 2.0) , which has few encryption methods, which returns us encrypted data.
Now this test library gives error when called those encryption methods from TestLibrary.
How can we consume those dll's in TestLibrary, and get the data on main project.
// below code is in TestLibrary
def get_encrypted_data():
try:
clr.AddReference('folder/dlls/EncryptionDLL')
from EncryptionDLL import EncryptionClass
encryptionObj = EncryptionClass()
encryptedData = encryptionObj.Encrypt('Data', 'Encryption Key')
return encryptedData
except Exception as e:
return e
//Below Code is in Flask Application
//pip install TestLibrary
from TestLibrary import get_encrypted_data
encryptedData = get_encrypted_data(); //Error here, not able to read dll
I have tried it with, PythonNet, LibMono installation. It works fine when created a POC with only that dll in python.
When we place it another library and consume that library, we are getting error.

Mismatched protocol version in packet Error: lost sync or rosserial_python is from different ros release than the rosserial client

I am using a raspberry pi 4 mode B to interface communicate with a Teensy 4.0. I'm using ROS noetic on Ubuntu 20.04. I've flashed the code to the Teensy successfully using platformio. I have a problem, however, when I try and launch the calibration python script for the robot I'm working on. I'm interfacing the raspberry Pi with the Teensy through the GPIO pins (this is after I've flashed the code to the Teensy, I flashed it through usb). When I run the calibration script using roslaunch mini_ros spot_calibration I get the following error:
[servo_calibration-1] process has died [pid 4841, exit code 1, cmd /home/ubuntu/spark_ws/src/spot_mini_mini/mini_ros/src/servo_calibration __name:=servo_calibration __log:=/home/ubuntu/.ros/log/fa068172-32ea-11ec-b45a-513494152363/servo_calibration-1.log].
log file: /home/ubuntu/.ros/log/fa068172-32ea-11ec-b45a-513494152363/servo_calibration-1*.log
[ERROR] [1634874547.846356]: Mismatched protocol version in packet (b'\xf8'): lost sync or rosserial_python is from different ros release than the rosserial client
below is the python code in spot_calibration
#!/usr/bin/env python
"""
DESCRIPTION:
SUBSCRIBERS:
"""
from __future__ import division
import rospy
from mini_ros.srv import CalibServo, CalibServoResponse
from mini_ros.msg import JointPulse
import numpy as np
import sys
import rospkg
rospack = rospkg.RosPack()
sys.path.append(rospack.get_path('mini_ros') + '/../')
sys.path.append('../../')
class ServoCalibrator():
def __init__(self):
rospy.init_node('ServoCalibrator', anonymous=True)
self.serv = rospy.Service('servo_calibrator', CalibServo,
self.calib_service_cb)
self.jp_pub = rospy.Publisher('spot/pulse', JointPulse, queue_size=1)
def calib_service_cb(self, req):
""" Requests a servo to be moved to a certain position
Args: req
Returns: response
"""
try:
jp_msg = JointPulse()
jp_msg.servo_num = req.servo_num
jp_msg.servo_pulse = req.servo_pulse
self.jp_pub.publish(jp_msg)
response = "Servo Command Sent."
except rospy.ROSInterruptException:
response = "FAILED to send Servo Command"
return CalibServoResponse(response)
def main():
""" The main() function. """
srv_calib = ServoCalibrator()
rospy.loginfo(
"Use The servo_calibrator service (Pulse Width Unit is us (nominal ~500-2500))."
)
while not rospy.is_shutdown():
rospy.spin()
if __name__ == '__main__':
try:
main()
except rospy.ROSInterruptException:
pass
The package was supposedly made in ROS Melodic, so that might be why it's throwing the error, but I don't know what to change if the package is melodic exclusive.
The problem is indeed because the roslib package used by rosserial was build for Melodic. As you can guess this error is just caused because of mismatched version ids coming from the arduino side. The best option would be to rebuild ros_lib for Noetic.
To rebuild ros_lib all you have to do is navigate to your sketchbook and run make_libraries.py. Note that this will build up to the currently installed distro, so you need to run this on a machine that has Noetic installed.
cd <sketchbook>/libraries
rm -rf ros_lib
rosrun rosserial_arduino make_libraries.py .
If rebuilding isn't an option you can add the definitions manually. On the arduino side you'll have a ros_lib folder. You have two sub directories you need to change.
The first is ./ros/node_handle.h. At the top of the file you'll see a few protocol versions defined as const uint8_t. Add in the version id for noetic as const uint8_t PROTOCOL_VER6 = 0xfa; then change the line that states what version should be used. const uint8_t PROTOCOL_VER = PROTOCOL_VER6;.
Lastly, you just need to make this same change in ./ros_lib/ros/node_handle.h

How to fix ALDialog Python Script NAOqi Error

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.

Error "-10814" when opening chrome url with webbrowser.open_new()

I run the following commands and receive execution error.
Here is my code:
import webbrowser
test = "chrome://chrome-urls/"
webbrowser.open_new(test)
Error:
0:37: execution error: An error of type -10814 has occurred. (-10814)
What is my mistake? I use Pycharm on MacOs
Well, it seems there isn't much on this error, but what I could find is that -10814 is a kLSApplicationNotFoundErr. It probably means that the OS launch services can't associate the given URL with a default app to open it, which makes sense since you are trying to open an internal chrome URL. It probably won't throw the same error with standard http/https URLs.
This code works fine for me.
import webbrowser
test = 'https://stackoverflow.com/'
ff = webbrowser.get('google-chrome')
ff.open(test)
But this does not.
import webbrowser
test = 'chrome://chrome-urls/'
ff = webbrowser.get('google-chrome')
ff.open(test)
Maybe you cannot open this type of urls.

Python urllib won't download file due to permissions, but wget will

I'm trying to download an MP3 file, via its URL, using Python's urllib2.
mp3file = urllib2.urlopen(url)
output = open(dst,'wb')
output.write(mp3file.read())
output.close()
I'm getting a urllib2.HTTPError: HTTP Error 403: Forbidden error.
Trying urllib also fails, but silently.
urllib.urlretrieve(url, dst)
However, if I use wget, I can download the file successfully.
I've noted the general differences between the two methods mentioned in "Difference between Python urllib.urlretrieve() and wget", but they don't seem to apply here.
Is wget doing something to negotiate permissions that urllib2 doesn't do? If so, what, and how do I replicate this in urllib2?
Could be something on the server side - blocking python user agent for example. Try using wget user agent : Wget/1.13.4 (linux-gnu) .
In Python 2:
import urllib
# Change header for User-Agent
class AppURLopener(urllib.FancyURLopener):
version = "Wget/1.13.4 (linux-gnu)"
url = "http://www.example.com/test_file"
fname = "test_file"
urllib._urlopener = AppURLopener()
urllib.urlretrieve(url, fname)
The above didn't work for me (I'm using python3.5). wget works fine.
It's not (I assume) a huge problem for me - surely I can still do a system() and use wget to get the data, with some file renaming and munging.
But in case anyone else is suffering from the same problem, these are the errors I get from the above snippet:
Traceback (most recent call last):
File "./mksynt.py", line 10, in <module>
class AppURLopener(urllib.FancyURLopener):
AttributeError: module 'urllib' has no attribute 'FancyURLopener'
I see that the original answer was only promised to work in python2.

Categories

Resources