I built a robot and setup local networking by having it act as an access point. I then connect to the access point from a laptop and send commands over UDP using python.
I would like to do the same thing but over the internet and Im really lost on how to get started. I've seen some IoT services but they dont seem well suited for such an application. I know some basics of networking enough to get a local network running but I have no idea how to get started on sending data over the internet.
Here is how I sent data over my local network (I would love to be able to do the same over the internet). I understand the requirements are a little different as I can't have a static IP address. If you could even point me to resources, I would appreciate it.
Note: the non-networking stuff is irrelevant to my question but I included it in the code for the sake of completion.
import pygame
import socket
import time
import math
#UDP_IP = "192.168.4.1" # if using ESP32
UDP_IP = "10.42.0.1" # if using jetson nano AP
UDP_PORT = 8080
l1=127/2
l2=127/2
r1=127/2
r2=127/2
intake = 127/2
elevator = 127/2
base_line=127/2
joy_deadzone= 0.2
'''
Joystick setup
'''
pygame.joystick.init()
pygame.init()
joysticks = [pygame.joystick.Joystick(x) for x in range(pygame.joystick.get_count())]
counter = 0
for joy in joysticks:
joy_index = counter
counter+=1
joysticks[joy_index].init()
print("The number of joysticks: " + str(pygame.joystick.get_count()))
print("The name of joystick: " + joysticks[joy_index].get_name())
print("The number of axis: " + str(joysticks[joy_index].get_numaxes()))
hats = joysticks[joy_index].get_numhats()
print ("Number of hats: {}".format(hats) )
'''
end of joystick setup
'''
time.sleep(1)
keepRunning = True
def numToStringF(num):
# Make each pwm value 3 characters
num = int(num)
ans = str(num)
if len(ans) == 1:
return "00" + ans
elif len(ans) == 2:
return "0" + ans
else:
return ans
axisX = 0;
axisY = 0;
X = 25;
up_button_last = False
down_button_last = False
left_button_last = False
right_button_last = False
while keepRunning:
#for event in pygame.event.get():
#time.sleep(1)
if abs(round(joysticks[joy_index].get_axis(3), 1))>joy_deadzone:
axisY = (round(joysticks[joy_index].get_axis(3), 1)) * -base_line
else:
axisY=0
if abs(round(joysticks[joy_index].get_axis(0), 1))>joy_deadzone:
axisX = round(joysticks[joy_index].get_axis(0), 1) * base_line
else:
axisX=0
if abs(round(joysticks[joy_index].get_axis(2), 1))>joy_deadzone:
axisS = round(joysticks[joy_index].get_axis(2), 1) * -base_line
else:
axisS=0
print('Calculated:')
print("X: " + str(axisX))
print("S: " + str(axisS))
print("Y: " + str(axisY) + "\n\n")
print('-------')
print('joystick axis:')
print(round(joysticks[joy_index].get_axis(3), 1))
print(round(joysticks[joy_index].get_axis(1), 1))
print('-------')
l1 = int(base_line+axisY+axisX-axisS)
l2 = int(base_line+-axisY-axisX-axisS)
r1 = int(base_line+axisY-axisX+axisS)
r2 = int(base_line+-axisY+axisX+axisS)
if(l1>127):
l1=127
elif(l1<0):
l1=0
if(l2>127):
l2=127
elif(l2<0):
l2=0
if(r1>127):
r1=127
elif(r1<0):
r1=0
if(r2>127):
r2=127
elif(r2<0):
r2=0
intake = int(base_line+joysticks[joy_index].get_button(14)*30)
elevator = int(base_line+joysticks[joy_index].get_button(14)*30)
print('the motors in sequence (l1,l2,r1,r2) are:')
print((l1,l2,r1,r2))
pygame.time.delay(50)
pygame.event.pump()
#time.sleep(0.1)
MESSAGE = "d" + numToStringF(l1) + numToStringF(l2)+numToStringF(r1)+numToStringF(r2)+numToStringF(intake)+numToStringF(elevator)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
sock.sendto(MESSAGE.encode("utf-8"), (UDP_IP, UDP_PORT))
print('the message sent is')
print(MESSAGE)
print('-----')
I ended up using firebase which has a real-time database and seems suitable for data streaming. I still have to do some testing to make sure it's good enough for robot control.
As for interfacing firebase with python, you can use this library:
https://github.com/thisbejim/Pyrebase
This doesn't seem to be a topic with many resources on the internet. I hope more roboticists discuss it/post tutorials and resources if they do some IoT-like robotics.
Related
I'm trying to integrate the neopixel LED on this Python ping script but I'm hitting a brick wall. All the time I try to integrate in response =0, the colorWIPE to activate the animation for response 0 the script crash.
import os
import platform
import subprocess
from rpi_ws281x import PixelStrip, Color
import argparse
# LED strip configuration:
LED_COUNT = 60 # Number of LED pixels.
LED_PIN = 18 # GPIO pin connected to the pixels (18 uses PWM!).
# LED_PIN = 10 # GPIO pin connected to the pixels (10 uses SPI /dev/spidev0.0).
LED_FREQ_HZ = 800000 # LED signal frequency in hertz (usually 800khz)
LED_DMA = 10 # DMA channel to use for generating signal (try 10)
LED_BRIGHTNESS = 255 # Set to 0 for darkest and 255 for brightest
LED_INVERT = False # True to invert the signal (when using NPN transistor level shift)
LED_CHANNEL = 0 # set to '1' for GPIOs 13, 19, 41, 45 or 53
plat = platform.system()
# Process arguments
parser = argparse.ArgumentParser()
parser.add_argument('-c', '--clear', action='store_true', help='clear the display on exit')
args = parser.parse_args()
# Create NeoPixel object with appropriate configuration.
strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)
# Intialize the library (must be called once before other functions).
strip.begin()
# Define functions which animate LEDs in various ways.
def colorWipe(strip, color, wait_ms=50):
"""Wipe color across display a pixel at a time."""
for i in range(strip.numPixels()):
strip.setPixelColor(i, color)
strip.show()
time.sleep(wait_ms / 1000.0)
def theaterChase(strip, color, wait_ms=50, iterations=10):
"""Movie theater light style chaser animation."""
for j in range(iterations):
for q in range(3):
for i in range(0, strip.numPixels(), 3):
strip.setPixelColor(i + q, color)
strip.show()
time.sleep(wait_ms / 1000.0)
for i in range(0, strip.numPixels(), 3):
strip.setPixelColor(i + q, 0)
def ping_return_code(hostname):
"""Use the ping utility to attempt to reach the host. We send 5 packets
('-c 5') and wait 3 milliseconds ('-W 3') for a response. The function
returns the return code from the ping utility.
"""
try:
if plat == "Windows":
# Checking for Windows Servers
response = subprocess.call(['ping', '-n', '5', '-W', '3', hostname],
stdout=open(os.devnull, 'w'),
stderr=open(os.devnull, 'w'))
elif plat == "Linux":
# Checking for Linux Servers
response = subprocess.call(['ping', '-c', '5', '-W', '3', hostname],
stdout=open(os.devnull, 'w'),
stderr=open(os.devnull, 'w'))
print ("Verify a host" + " " + '"' + hostname + '"' + " " + "for Network Reachability using PING Tool")
print ("---- Trying to Ping a Server with IPAddress ----", hostname)
# Check for response status code, Ping Success code is '0'
if response == 0:
print ("********************************************************************")
print(hostname, 'is UP and reachable!')
print ("********************************************************************")
# print "\n"
elif response == 1 or 2 or 256 or 512:
print ("********************************************************************")
print(hostname, 'is DOWN and No response from Server!')
print ("********************************************************************")
print ("\n")
except Exception:
print ("********************************************************************")
print(hostname, 'is DOWN and Host Unreachable!')
print ("********************************************************************")
print ("\n")
return response
def verify_hosts(host_list):
"""For each hostname in the list, attempt to reach it using ping. Returns a
dict in which the keys are the hostnames, and the values are the return
codes from ping. Assumes that the hostnames are valid.
"""
return_codes = dict()
for hostname in host_list:
return_codes[hostname] = ping_return_code(hostname)
return return_codes
def main():
# List of IP-address/Hosts for Ping test
hosts_to_test = [
"127.0.0.1",
"192.168.10.5",
]
verify_hosts(hosts_to_test)
if __name__ == '__main__':
main()
'''
I program an app witgh QT interface to read modbus data, I display data on GUI create with PyQT5.
When I launch program, it crash after few second, I haven't message error. I used debugger and nothing wrong thing, program just close.
This is a part of my code where is my problem, I'll explain after
def displayModbus(self):
modbusReturn = modbus.readModbus()
commStatus = modbusReturn[0]
if commStatus:
listRegValue = modbusReturn[1]
#Display data to ui
if str(listRegValue[1]) == "1": #HEATING_ST
self.ui.lnHeatingStatus.setText("On")
else:
self.ui.lnHeatingStatus.setText("Off")
# self.ui..setText(str(listRegValue[2])) #WAIT_TIME_CHG
# self.ui..setText(str(listRegValue[3])) #RUN_TIME_CHG
if str(listRegValue[4]) == "1": #ON_WAIT_TIME_P
self.ui.ledWaitTime.setStyleSheet("QPushButton {background-color:green;}")
else:
self.ui.ledWaitTime.setStyleSheet("QPushButton {background-color:red;}")
if str(listRegValue[5]) == "1": #RUN_CYCLE
self.ui.lnRunCycle.setText("On")
else:
self.ui.lnRunCycle.setText("Off")
# self.ui..setText(str(listRegValue[6])) #LEVEL_RESET
# self.ui..setText(str(listRegValue[7])) #CYL_MAN_CYCLE
# self.ui..setText(str(listRegValue[8])) #CYL_EMPTY
# self.ui..setText(str(listRegValue[9])) #CYL_EMPTY_END
# self.ui..setText(str(listRegValue[10])) #NORASYSTEM_MANUAL
# self.ui..setText(str(listRegValue[11])) #NORASYSTEM_ON
# self.ui..setText(str(listRegValue[12])) #HEATING_ALLOW
if str(listRegValue[13]) == "1": #LOW_AIRFLOW
self.ui.lnLowAirflow.setText("Low")
else:
self.ui.lnLowAirflow.setText("Normal")
# self.ui..setText(str(listRegValue[15])) #HUM_ALLOW
TC1 = listRegValue[16] / 100
self.ui.lnTC1.setText(str(TC1)+" °C") #TC1
TC2 = listRegValue[17] / 100
self.ui.lnTC2.setText(str(TC2)+" °C") #TC2
TC3 = listRegValue[18] / 100
self.ui.lnTC3.setText(str(TC3)+" °C") #TC3
TC4 = listRegValue[19] / 100
self.ui.lnTC4.setText(str(TC4)+" °C") #TC4
self.ui.lnH1.setText(str(listRegValue[20])+" %RH") #HUM1
waitTime = str(listRegValue[22] / 3600)
self.ui.lnWaitTime.setText(str(waitTime+" hr")) #WAIT_TIME_D
runTime = str(listRegValue[23] / 60)
self.ui.lnRunTime.setText(str(runTime+" min")) #RUN_TIME_D
timeRemainM = str(int(listRegValue[24] / 60))
timeRemainS = str(int(listRegValue[24] % 60))
self.ui.lnTimeRemain.setText(str(timeRemainM + " min "+timeRemainS + " sec")) #TIME_REMAIN_D
self.ui.lnLevel.setText(str(listRegValue[25])) #LEVEL_D
self.statusBar().showMessage("Modbus communication OK")
else:
self.statusBar().showMessage("Error modbus communication")
The problem come from this function after many try and error method. If I delete it program doesn't crash BUT if I modify it by print function (example: print(str(listRegValue[4]))) all is good so my problem doesn't come from mGUI assignation odbus module.
my function displayModbus is refresh every 5 second (using QtThreading).
If I keep just one variable to display my app doesn't crash.
I have another app to read and record modbus data using same displayModbus function (without QT5 display) and I haven't problem
I have this problem on 2 computers and I try it on 5 computers (4x windows 10 and 1x Linux)
Python 3.8.6
PyQT==5.15.1
PyQt5-sip==12.8.1
Any idea?
Thanks.
In visual studio I am trying to upload my code onto the ev3de (which is in python). It does work but as soon as I try to run it on the ev3, the program goes straight back to the screen before. When I try and run the program there are a few errors: It cannot find a module called pyev3, which I have never heard of, and it also cannot find the cwiid module, for the wiimote. Here is the code (it's not from myself):
#!/usr/bin/env python3
# Drive your robot with a wii remote!
# Left motor on port B, right motor on port C,
# vertical arm on port D.
# Requires the package 'python-cwiid'.
# Make sure bluetooth is enabled in brickman
# before trying to use this. Hold 2 to go forward
# and 1 to go backward.
import sys
import os
import time
import cwiid
import pyev3
def clamp(value, lower, upper):
return min(upper, max(value, lower))
print('press 1+2 on the wiimote now')
time.sleep(1)
w = cwiid.Wiimote()
print('connected?')
w.led = 6
w.rpt_mode = cwiid.RPT_ACC | cwiid.RPT_BTN
left_motor = pyev3.Motor(pyev3.OUTPUT_B)
left_motor.reset()
left_motor.run_mode = 'forever'
left_motor.regulation_mode = 'on'
right_motor = pyev3.Motor(pyev3.OUTPUT_C)
right_motor.reset()
right_motor.run_mode = 'forever'
right_motor.regulation_mode = 'on'
arm = pyev3.Motor(pyev3.OUTPUT_D)
arm.reset()
arm.run_mode = 'forever'
arm.regulation_mode = 'off'
target_distance = 8
top_speed = 720
left_motor.run = 1
right_motor.run = 1
last_btn_state = 0
move = 0
try:
while True:
state = w.state
buttons = state['buttons']
if buttons != last_btn_state:
if buttons & cwiid.BTN_MINUS:
top_speed -= 10
print (top_speed)
if buttons & cwiid.BTN_PLUS:
top_speed += 10
print (top_speed)
if buttons & cwiid.BTN_2:
move = 1
elif buttons & cwiid.BTN_1:
move = -1
else:
move = 0
if buttons & cwiid.BTN_LEFT:
arm.duty_cycle_sp = 100
arm.run = 1
elif buttons & cwiid.BTN_RIGHT:
arm.duty_cycle_sp = -100
arm.run = 1
else:
arm.run = 0
print (top_speed, move)
last_btn_state = buttons
if move:
acc = state['acc']
tilt = (clamp(acc[1], 95, 145) - 120) / 25.0 # roughly between -0.5 and 0.5
turn = top_speed * tilt
turn = clamp(turn, -abs(top_speed), abs(top_speed))
left_motor.pulses_per_second_sp = int(top_speed - turn) * move
right_motor.pulses_per_second_sp = int(top_speed + turn) * move
else:
left_motor.pulses_per_second_sp = 0
right_motor.pulses_per_second_sp = 0
finally:
left_motor.run = 0
right_motor.run = 0
When I run this one in Visual Studio Code, this happens:
File "c:/Users/User/Documents/fingers_crossed/drive.py", line 13, in
import cwiid ModuleNotFoundError: No module named 'cwiid' PS
C:\Users\User\Documents\fingers_crossed>
Also, why can't my robot find the ev3dev2 module?
These days I have tried to generate an application using the pythonapp template from the Github project Jumpstarter(https://github.com/aldebaran/robot-jumpstarter) to do the localization of Pepper. My basic idea is to combine the LandmarkDetector module in the generated app „Lokalisierung“(Localization of German).
You can read the whole code of "LandmarkDetector.py","main.py" and"MainLandmarkDetection.py" here:
"LandmarkDetector.py":
#! /usr/bin/env python
# -*- encoding: UTF-8 -*-
"""Example: Demonstrates a way to localize the robot with
ALLandMarkDetection"""
import qi
import time
import sys
import argparse
import math
import almath
class LandmarkDetector(object):
"""
We first instantiate a proxy to the ALLandMarkDetection module
Note that this module should be loaded on the robot's naoqi.
The module output its results in ALMemory in a variable
called "LandmarkDetected".
We then read this ALMemory value and check whether we get
interesting things.
After that we get the related position of the landmark compared to robot.
"""
def __init__(self, app):
"""
Initialisation of qi framework and event detection.
"""
super(LandmarkDetector, self).__init__()
app.start()
session = app.session
# Get the service ALMemory.
self.memory = session.service("ALMemory")
# Connect the event callback.
# Get the services ALMotion & ALRobotPosture.
self.motion_service = session.service("ALMotion")
self.posture_service = session.service("ALRobotPosture")
self.subscriber = self.memory.subscriber("LandmarkDetected")
print "self.subscriber = self.memory.subscriber(LandmarkDetected)"
self.subscriber.signal.connect(self.on_landmark_detected)
print "self.subscriber.signal.connect(self.on_landmark_detected)"
# Get the services ALTextToSpeech, ALLandMarkDetection and ALMotion.
self.tts = session.service("ALTextToSpeech")
self.landmark_detection = session.service("ALLandMarkDetection")
# print "self.landmark_detection" is repr(self.landmark_detection)
self.motion_service = session.service("ALMotion")
self.landmark_detection.subscribe("LandmarkDetector", 500, 0.0 )
print "self.landmark_detection.subscribe(LandmarkDetector, 500, 0.0 )"
self.got_landmark = False
# Set here the size of the landmark in meters.
self.landmarkTheoreticalSize = 0.06 #in meters 0 #.05 or 0.06?
# Set here the current camera ("CameraTop" or "CameraBottom").
self.currentCamera = "CameraTop"
def on_landmark_detected(self, markData):
"""
Callback for event LandmarkDetected.
"""
while markData == [] : # empty value when the landmark disappears
self.got_landmark = False
self.motion_service.moveTo(0, 0, 0.1 * math.pi)
if not self.got_landmark: # only speak the first time a landmark appears
self.got_landmark = True
#stop.motion_service.moveTo
print "Ich sehe eine Landmarke! "
self.tts.say("Ich sehe eine Landmarke! ")
# Retrieve landmark center position in radians.
wzCamera = markData[1][0][0][1]
wyCamera = markData[1][0][0][2]
# Retrieve landmark angular size in radians.
angularSize = markData[1][0][0][3]
# Compute distance to landmark.
distanceFromCameraToLandmark = self.landmarkTheoreticalSize / ( 2 * math.tan( angularSize / 2))
# Get current camera position in NAO space.
transform = self.motion_service.getTransform(self.currentCamera, 2, True)
transformList = almath.vectorFloat(transform)
robotToCamera = almath.Transform(transformList)
# Compute the rotation to point towards the landmark.
cameraToLandmarkRotationTransform = almath.Transform_from3DRotation(0, wyCamera, wzCamera)
# Compute the translation to reach the landmark.
cameraToLandmarkTranslationTransform = almath.Transform(distanceFromCameraToLandmark, 0, 0)
# Combine all transformations to get the landmark position in NAO space.
robotToLandmark = robotToCamera * cameraToLandmarkRotationTransform *cameraToLandmarkTranslationTransform
# robotTurnAroundAngle = almath.rotationFromAngleDirection(0, 1, 1, 1)
# print "robotTurnAroundAngle = ", robotTurnAroundAngle
print "x " + str(robotToLandmark.r1_c4) + " (in meters)"
print "y " + str(robotToLandmark.r2_c4) + " (in meters)"
print "z " + str(robotToLandmark.r3_c4) + " (in meters)"
def run(self):
"""
Loop on, wait for events until manual interruption.
"""
# Wake up robot
self.motion_service.wakeUp()
# Send robot to Pose Init
self.posture_service.goToPosture("StandInit", 0.5)
# Example showing how to get a simplified robot position in world.
useSensorValues = False
result = self.motion_service.getRobotPosition(useSensorValues)
print "Robot Position", result
# Example showing how to use this information to know the robot's diplacement.
useSensorValues = False
# initRobotPosition = almath.Pose2D(self.motion_service.getRobotPosition(useSensorValues))
# Make the robot move
for i in range(1, 12, 1):
self.motion_service.moveTo(0, 0, 0.1 * math.pi)
print "self.motion_service.moveTo(0, 0, (0.1)*math.pi)"
print "Starting LandmarkDetector"
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
print "Interrupted by user, stopping LandmarkDetector"
self.landmark_detection.unsubscribe("LandmarkDetector")
#stop
sys.exit(0)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--ip", type=str, default="10.0.0.10",
help="Robot IP address. On robot or Local Naoqi: use
'10.0.0.10'.")
parser.add_argument("--port", type=int, default=9559,
help="Naoqi port number")
args = parser.parse_args()
try:
# Initialize qi framework.
connection_url = "tcp://" + args.ip + ":" + str(args.port)
app = qi.Application(["LandmarkDetector", "--qi-url=" + connection_url])
except RuntimeError:
print ("Can't connect to Naoqi at ip \"" + args.ip + "\" on port " + str(args.port) +".\n"
"Please check your script arguments. Run with -h option for help.")
sys.exit(1)
landmark_detector = LandmarkDetector(app)
landmark_detector.run()
"main.py":
""" A sample showing how to make a Python script as an app. """
version = "0.0.8"
copyright = "Copyright 2015, Aldebaran Robotics"
author = 'YOURNAME'
email = 'YOUREMAIL#aldebaran.com'
import stk.runner
import stk.events
import stk.services
import stk.logging
class Activity(object):
"A sample standalone app, that demonstrates simple Python usage"
APP_ID = "com.aldebaran.lokalisierung"
def __init__(self, qiapp):
self.qiapp = qiapp
self.events = stk.events.EventHelper(qiapp.session)
self.s = stk.services.ServiceCache(qiapp.session)
self.logger = stk.logging.get_logger(qiapp.session, self.APP_ID)
def on_touched(self, *args):
"Callback for tablet touched."
if args:
self.events.disconnect("ALTabletService.onTouchDown")
self.logger.info("Tablet touched: " + str(args))
self.s.ALTextToSpeech.say("Yay!")
self.stop()
def on_start(self):
"Ask to be touched, waits, and exits."
# Two ways of waiting for events
# 1) block until it's called
self.s.ALTextToSpeech.say("Touch my forehead.")
self.logger.warning("Listening for touch...")
while not self.events.wait_for("FrontTactilTouched"):
pass
# 2) explicitly connect a callback
if self.s.ALTabletService:
self.events.connect("ALTabletService.onTouchDown", self.on_touched)
self.s.ALTextToSpeech.say("okay, now touch my tablet.")
# (this allows to simltaneously speak and watch an event)
else:
self.s.ALTextToSpeech.say("touch my tablet ... oh. " + \
"I don't haave one.")
self.stop()
def stop(self):
"Standard way of stopping the application."
self.qiapp.stop()
def on_stop(self):
"Cleanup"
self.logger.info("Application finished.")
self.events.clear()
if __name__ == "__main__":
stk.runner.run_activity(Activity)
"MainLandmarkDetection.py":
#! /usr/bin/env python
# -*- encoding: UTF-8 -*-
"""A sample showing how to make a Python script as an app to localize
the robot with ALLandMarkDetection"""
version = "0.0.8"
copyright = "Copyright 2015, Aldebaran Robotics"
author = 'YOURNAME'
email = 'YOUREMAIL#aldebaran.com'
import stk.runner
import stk.events
import stk.services
import stk.logging
import time
import sys
import math
import almath
class Activity(object):
"A sample standalone app, that demonstrates simple Python usage"
APP_ID = "com.aldebaran.lokalisierung"
def __init__(self, qiapp):
self.qiapp = qiapp
self.events = stk.events.EventHelper(qiapp.session)
self.s = stk.services.ServiceCache(qiapp.session)
self.logger = stk.logging.get_logger(qiapp.session, self.APP_ID)
self.qiapp.start()
session = qiapp.session
# Get the service ALMemory.
self.memory = session.service("ALMemory")
# Connect the event callback.
# Get the services ALMotion & ALRobotPosture.
self.motion_service = session.service("ALMotion")
self.posture_service = session.service("ALRobotPosture")
self.subscriber = self.memory.subscriber("LandmarkDetected")
print "self.subscriber = self.memory.subscriber(LandmarkDetected)"
self.subscriber.signal.connect(self.on_landmark_detected)
print "self.subscriber.signal.connect(self.on_landmark_detected)"
# Get the services ALTextToSpeech, ALLandMarkDetection and ALMotion.
self.tts = session.service("ALTextToSpeech")
self.landmark_detection = session.service("ALLandMarkDetection")
# print "self.landmark_detection" is repr(self.landmark_detection)
self.motion_service = session.service("ALMotion")
self.landmark_detection.subscribe("Activity", 500, 0.0)
print "self.landmark_detection.subscribe(Activity, 500, 0.0 )"
self.got_landmark = False
# Set here the size of the landmark in meters.
self.landmarkTheoreticalSize = 0.06 # in meters 0 #.05 or 0.06?
# Set here the current camera ("CameraTop" or "CameraBottom").
self.currentCamera = "CameraTop"
def on_landmark_detected(self, markData):
"""
Callback for event LandmarkDetected.
"""
while markData == []: # empty value when the landmark disappears
self.got_landmark = False
# self.motion_service.moveTo(0, 0, 0.1 * math.pi)
if not self.got_landmark: # only speak the first time a landmark appears
self.got_landmark = True
# stop.motion_service.moveTo
print "Ich sehe eine Landmarke! "
# self.tts.say("Ich sehe eine Landmarke! ")
# Retrieve landmark center position in radians.
wzCamera = markData[1][0][0][1]
wyCamera = markData[1][0][0][2]
# Retrieve landmark angular size in radians.
angularSize = markData[1][0][0][3]
# Compute distance to landmark.
distanceFromCameraToLandmark = self.landmarkTheoreticalSize / (2 * math.tan(angularSize / 2))
# Get current camera position in NAO space.
transform = self.motion_service.getTransform(self.currentCamera, 2, True)
transformList = almath.vectorFloat(transform)
robotToCamera = almath.Transform(transformList)
# Compute the rotation to point towards the landmark.
cameraToLandmarkRotationTransform = almath.Transform_from3DRotation(0, wyCamera, wzCamera)
# Compute the translation to reach the landmark.
cameraToLandmarkTranslationTransform = almath.Transform(distanceFromCameraToLandmark, 0, 0)
# Combine all transformations to get the landmark position in NAO space.
robotToLandmark = robotToCamera * cameraToLandmarkRotationTransform * cameraToLandmarkTranslationTransform
# robotTurnAroundAngle = almath.rotationFromAngleDirection(0, 1, 1, 1)
# print "robotTurnAroundAngle = ", robotTurnAroundAngle
print "x " + str(robotToLandmark.r1_c4) + " (in meters)"
print "y " + str(robotToLandmark.r2_c4) + " (in meters)"
print "z " + str(robotToLandmark.r3_c4) + " (in meters)"
def run(self):
"""
Loop on, wait for events until manual interruption.
"""
# Wake up robot
self.motion_service.wakeUp()
# Send robot to Pose Init
self.posture_service.goToPosture("StandInit", 0.5)
# Example showing how to get a simplified robot position in world.
useSensorValues = False
result = self.motion_service.getRobotPosition(useSensorValues)
print "Robot Position", result
# Example showing how to use this information to know the robot's diplacement.
useSensorValues = False
# initRobotPosition = almath.Pose2D(self.motion_service.getRobotPosition(useSensorValues))
# Make the robot move
for i in range(1, 20, 1):
self.motion_service.moveTo(0, 0, 0.1 * math.pi)
print "self.motion_service.moveTo(0, 0, (0.1)*math.pi)"
print "Starting Activity"
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
print "Interrupted by user, stopping Activity"
self.landmark_detection.unsubscribe("Activity")
# stop
sys.exit(0)
def stop(self):
"Standard way of stopping the application."
self.qiapp.stop()
def on_stop(self):
"Cleanup"
self.logger.info("Application finished.")
self.events.clear()
if __name__ == "__main__":
stk.runner.run_activity(Activity)
landmark_detector = Activity()
landmark_detector.run()
This is how it worked in cmd.exe:
And I have a question to the parameter by ”landmark_detector = Activity()” in line 157 at almost the end of the program because of the Error in the image, which I should pass. After reading the answers to the similar question here by StackoverflowPython: TypeError: __init__() takes exactly 2 arguments (1 given), I am still confused. I think it should be a value which is given to the "qiapp", but what value?
Best regards,
Frederik
Actually, when you call
stk.runner.run_activity(Activity)
... it will instantiate that activity object for you, with the right parameters, you don't need to landmark_detector = Activity() etc. in MainLandmarkDetector.py
And if this object has a method called on_start, that method will be called once everything is ready (so you may only need to rename your run() method to on_start()
Note also that instead of calling sys.stop(), you can just call self.stop() or self.qiapp.stop() (which is a bit cleaner in terms of letting the cleanup code in on_stop to be called, if you need to unsubscribe to things etc.)
See here for some documentation on stk.runner.
Note also that instead of doing
self.motion_service = session.service("ALMotion")
(...)
transform = self.motion_service.getTransform(self.currentCamera, 2, True)
you can directly do
transform = self.s.ALMotion.getTransform(self.currentCamera, 2, True)
... which (in my opinion) makes it easier to see what is being done exactly (and reduces the number of variables).
I'm trying to develop a multithread function in python 3.6 and sometime my code freeze. from my tests I think that the problem come from os.write() or os.read(), but I don't know why.
here is my code (I don't think that partialTransform() cause the freeze but I put it to understand the code):
def naiveTransform(netData,**kwargs):
#parralelisable part
def partialTransform(debut, fin) :
for i in range(debut, fin) :
j = 0
#calcul of all the distances :
while j < nbrPoint :
distance[j] = euclidianDistance(netData[i], netData[j])
j += 1
#construction of the graph :
j = 0
del distance[i]
while j < k :
nearest = min(distance, key=distance.get)
del distance[nearest] #if k > 1 we don't want to get always the same point.
graph.append([i, nearest])
j += 1
return graph
k = kwargs.get('k', 1) # valeur par défault à definir.
nbrCore = kwargs.get('Core', 1)
nbrPoint = len(netData)
nbrPointCore = nbrPoint//nbrCore
distance = dict()
graph = []
#pipes
r = [-1]*nbrCore
w = [-1]*nbrCore
pid = [-1]*nbrCore
for i in range(nbrCore):
r[i], w[i] = os.pipe()
try:
pid[i] = os.fork()
except OSError:
exit("Could not create a child process\n")
if pid[i] == 0:
if i < nbrCore-1 :
g = partialTransform(i*nbrPointCore, (i+1)*nbrPointCore)
else :
g = partialTransform(i*nbrPointCore, nbrPoint) #to be sure that there is not a forgoten point.
print("write in " + str(i))
import sys
print(sys.getsizeof(g))
os.write(w[i], pickle.dumps(g))
print("exit")
exit()
for i in range(nbrCore):
print("waiting " + str(i))
finished = os.waitpid(pid[i], 0)
print("received")
graph += pickle.loads(os.read(r[i], 250000000))
return graph
When the argument k is superior or equal to 5 the code freeze after the
print(sys.getsizeof(g))
For my example case when k = 4 the size is of 33928 and for k = 5 the size is of 43040 so I don't think that it's the problem ?
The number of core used don't seem to have any influence on the freeze.
I'm still a beginner in python so it may be something obvious but I didn't find any similar problem on internet. Do you have any idea of what could cause theses freeze ?
Pipes have limited size buffers and the child will block writing the pipe until the parent reads it. But the parent is waiting for the child to exit, so you hang. You can avoid the buffer limit by writing the object to a temporary file instead. The data will be in the operation system file cache when the parent reads so it will still be fast.
There is a trick in all this. The parent needs to convince libc to re-examine the file after the child writes it or the read will just be satisfied by its 0 length internal cache. You can do that with a seek.
import tempfile
def naiveTransform(netData,**kwargs):
// *** code removed for example ***
# files
tmp = [tempfile.TemporaryFile() for _ in range(nbrCore)]
pid = [-1]*nbrCore
for i in range(nbrCore):
try:
pid[i] = os.fork()
except OSError:
exit("Could not create a child process\n")
if pid[i] == 0:
if i < nbrCore-1 :
g = partialTransform(i*nbrPointCore, (i+1)*nbrPointCore)
else :
g = partialTransform(i*nbrPointCore, nbrPoint) #to be sure that there is not a forgoten point.
print("write in " + str(i))
import sys
print(sys.getsizeof(g))
pickle.dump(g, tmp[i])
tmp[i].close()
print("exit")
exit()
for i in range(nbrCore):
print("waiting " + str(i))
finished = os.waitpid(pid[i], 0)
print("received")
# seek to get updated file content
tmp[i].seek(0,2)
tmp[i].seek(0)
graph += pickle.load(tmp[i])
return graph