Pepper human detection - pepper

I want to detect people without relying on face detection. In cases where lighting conditions are poor, or Pepper is facing away, people are not detected.
The memory events 'PeoplePerception/JustArrived' and 'EngagementZones/PersonApproached' seem to rely on faces being detectable by the camera.
Is there a memory event which is triggered by changes in laser/infrared/sonar distance?
I wonder if there is a better solution than:
while True:
floatDist = self.memory.getData('Device/SubDeviceList/Platform/Front/Sonar/Sensor/Value')
if floatDist < 1.0:
doSomething()
sleep(0.5)

You can use the front sonar and the event "FaceDetected" for the human detection.
But you can use a PeriodicTask and not a while loop. You while check the event each 0.5secs and you will be allowed to stop it.
I will do it like that :
class HumanDetector:
def __init__(self, ALMemory):
self.ALMemory = ALMemory
# subscribe to FaceDetected
self.subscriber = self.ALMemory.subscriber("FaceDetected")
self.subscriber.signal.connect(self.on_human_tracked)
self.task = qi.PeriodicTask()
self.task.setCallback(self._task)
self.task.setUsPeriod(50000)
self.task.start(True)
def on_human_tracked(self, value):
print "do something with the face"
def _stop(self):
print "_stop..."
self.task.stop()
self.face_detection.unsubscribe("FaceDetected")
print "_stop done"
def _task(self):
print "_task..."
floatDist = self.memory.getData('Device/SubDeviceList/Platform/Front/Sonar/Sensor/Value')
if floatDist < 1.0:
print "do something with the object in front of the robot"
print "_task done"
So it is an example of a python Class that need the module ALMemory.
With the module ALMemory you will check the sonar and if a face is detected.

Related

maintain resolution in mayavi or vtk during object rotation

In my application a user interacts with a 3D volumetric rendering. The data is quite noisy, but there are objects of interest buried in the noise. My users are able to get a good geometric sense of these objects by rotating and panning the scene.
Resolution is still crucial and I might be willing to trade it off for smoothness of interaction. Can I disable or at least modify this downsampling/lowering-of-resolution that accompanies scene interaction?
I've been asked to show my code.. I'll show some pieces.
class Display(HasTraits)
def __init__(self, list_of_MySourceObjects , list_of_corresponding_MyScenes )
...
def default_traits_view(self):
traits_view=View(HGroup( *list_ofMyScenes ) ##Allows variable number of scenes in view
...
class SomeSensibleCoordinateClass(HasTraits):
#Some logic for coordinate callbacks and manipulation
...
####Custom class that knows how to plot on scenes####
class MySourceObject(SomeSensibleCoordinateClass):
...
###I'll show a sample plotting function
def display_on_small_scene(self,scene):
self.origin=-self.radius.__array__()*self.spacing
print 'origin is',self.origin
self.small_array_src=ArraySource(scene,spacing=self.spacing,origin=self.origin)
self.scene=scene#for debug
self.set_scene_patch()### (re)sets self.array_src data
scene.mayavi_scene.add_child(self.array_src)
self.volume=self.array_src.add_module(self.vol_module)
scene.draw_axes(self.array_src.scalar_data.shape)
...
class MyScene(MlabSceneModel):
volume=Instance(Volume,())
some_other_custom_parameters = Any()
...
##Some default picking behavior
def picker_callback(self...):
...
##Some default aesthetics
def draw_axes(self,...):

how to group traits together, encapsulating them as a group

I have a coordinate system that it makes sense to treat as a "whole group". They initialize, change, and reset simultaneously. I also like to not re-render as many times as I have coordinates when one changes. Here is the simplified version of what I have in mind, but I can't quite get there. Thanks.
Cleaner code is better in my case even if it uses more advanced features. Could the class 'Coord' be wrapped as a trait itself?
from traits.api import *
class Coord(HasTraits):
x=Float(1.0)
y=Float(1.0)
def __init__(self,**traits):
HasTraits.__init__(self,**traits)
class Model:
coord=Instance(Coord)
#on_trait_change('coord')##I would so have liked this to "just work"
def render(self):#reupdate render whenever coordinates change
class Visualization:
model=Instance(Model)
def increment_x(self):
self.model.coord.x+=1 ##should play well with Model.render
def new_coord(self):
self.model.coord=Coord(x=2,y=2) ##should play well with Model.render
There are a couple of issues with your source code. Model and Visualization both need to be HasTraits classes for the listener to work.
Also, it is rare to actually need to write the __init__ method of a HasTraits class. Traits is designed to work without it. That said, if you do write an __init__ method, make sure to use super to properly traverse the method resolution order. (Note that you will find this inconsistently implemented in the extant documentation and examples.)
Finally, use the 'anytrait' name to listen for any trait:
from traits.api import Float, HasTraits, Instance, on_trait_change
class Coord(HasTraits):
x=Float(1.0)
y=Float(1.0)
class Model(HasTraits):
coord=Instance(Coord, ())
#on_trait_change('coord.anytrait') # listens for any trait on `coord`.
def render(self):
print "I updated"
class Visualization(HasTraits):
model=Instance(Model, ())
def increment_x(self):
self.model.coord.x+=1 # plays well with Model.render
def new_coord(self):
self.model.coord=Coord(x=2,y=2) # plays well with Model.render
Here's my output:
>>> v = Visualization()
>>> v.increment_x()
I updated
>>> v.new_coord()
I updated

Python tk(): No window appears when using in scripts (console works)

I have the following problem with this easy script:
from Tkinter import *
root = Tk()
while 1:
pass
I think, after the 2nd line everyone would expect a Tkinter window would appear. But it does not!
If I put this line into the Python console (without the endless-while-loop), it works.
[I wanted to add an image here, but as I'm new I'm to allowed to :-(]
But running the script (double-clicking on the *.py file in the Windows Explorer) results only in an empty Python console!
Background:
Actually I want to use Snack for Python. This is based on Tkinter. That means I have to create an Tk() instance first. Everything works fine in the Python console. But I want to write a bigger program with at least one Python script thus I cannot type the whole program into the console everytime :-)
I have installed Python 2.7 and Tcl/Tk 8.5 (remember: it works in the console)
EDIT: So here's my solution:
First, I create a class CSoundPlayer:
from Tkinter import*
import tkSnack
class CSoundPlayer:
def __init__(self, callbackFunction):
self.__activated = False
self.__callbackFunction = callbackFunction
self.__sounds = []
self.__numberOfSounds = 0
self.__root = Tk()
self.__root.title("SoundPlayer")
tkSnack.initializeSnack(self.__root)
def __mainFunction(self):
self.__callbackFunction()
self.__root.after(1, self.__mainFunction)
pass
def activate(self):
self.__activated = True
self.__root.after(1, self.__mainFunction)
self.__root.mainloop()
def loadFile(self, fileName):
if self.__activated:
self.__sounds.append(tkSnack.Sound(load=fileName))
self.__numberOfSounds += 1
# return the index of the new sound
return self.__numberOfSounds - 1
else:
return -1
def play(self, soundIndex):
if self.__activated:
self.__sounds[soundIndex].play()
else:
return -1
Then, the application itself must be implemented in a class thus the main() is defined when handed over to the CSoundPlayer() constructor:
class CApplication:
def __init__(self):
self.__programCounter = -1
self.__SoundPlayer = CSoundPlayer(self.main)
self.__SoundPlayer.activate()
def main(self):
self.__programCounter += 1
if self.__programCounter == 0:
self.__sound1 = self.__SoundPlayer.loadFile("../mysong.mp3")
self.__SoundPlayer.play(self.__sound1)
# here the cyclic code starts:
print self.__programCounter
CApplication()
As you can see, the mainloop() is called not in the constructor but in the activate() method. This is because the CApplication won't ever get the reference to CSoundPlayer object because that stucks in the mainloop.
The code of the class CApplication itself does a lot of overhead. The actual "application code" is placed inside the CApplication.main() - code which shall be executed only once is controlled by means of the program counter.
Now I put it to the next level and place a polling process of the MIDI Device in the CApplication.main(). Thus I will use MIDI commands as trigger for playing sound files. I hope the performance is sufficient for appropriate latency.
Have you any suggestions for optimization?
You must start the event loop. Without the event loop, tkinter has no way to actually draw the window. Remove the while loop and replace it with mainloop:
from Tkinter import *
root = Tk()
root.mainloop()
If you need to do polling (as mentioned in the comments to the question), write a function that polls, and have that function run every periodically with after:
def poll():
<do the polling here>
# in 100ms, call the poll function again
root.after(100, poll)
The reason you don't need mainloop in the console depends on what you mean by "the console". In IDLE, and perhaps some other interactive interpreters, tkinter has a special mode when running interactively that doesn't require you call mainloop. In essence, the mainloop is the console input loop.

Trace not working on Python TKinter checkbutton control

I'm doing my own tweak on the technique from this post, using a canvas vs. a text widget to get some finer control over the scrolling behavior. My code appears below.
All is working as I want it but for some reason the trace I'm using to track the checkbutton values isn't working. No errors of any kind show up in the console window. But I don't get the expected printed message (from _cbWasClicked) when I click one any of the checkbuttons. As best I can tell the method is just never invoked.
I know it's got to be a simple and obvious bug but I'm stumped. I've used print statements to confirm that the 100 IntVars get instantiated as expected. Then I deliberately misspelled the method name in the .trace and this time it generated an error. So when I yank those diagnostic tweaks all should be working.... it just isn't. Can someone tell me what I'm missing?
Environment is Python 2.7 on Windows 7.
import Tkinter as tk
class myCheckList(tk.Frame):
def __init__(self, root, *args, **kwargs):
tk.Frame.__init__(self, root, *args, **kwargs)
self.root = root
self.vsb = tk.Scrollbar(self, orient="vertical")
self.canvas = tk.Canvas(self, width=200, height=290,
relief=tk.GROOVE,bd=3,
scrollregion=(0,0,0,2020),
yscrollcommand=self.vsb.set,
yscrollincrement=20)
basecolor = self.canvas.cget('background')
self.vsb.config(command=self.canvas.yview)
self.canvas.grid(row=0,column=0,sticky=tk.NSEW,padx=(0,0),pady=0)
self.vsb.grid(row=0,column=1,sticky=tk.NS,padx=(0,0),pady=0)
for i in range(100):
cbv = tk.IntVar()
cbv.trace('w',self._cbWasClicked)
cb = tk.Checkbutton(self, background=basecolor,
variable=cbv,
text="Checkbutton #%s" % i)
self.canvas.create_window(5,20*i+5,anchor=tk.NW,window=cb)
self.canvas.bind_all('<MouseWheel>',
lambda event: self.canvas.yview_scroll(-1*event.delta/120, tk.UNITS))
def _cbWasClicked(self,*args):
print 'checkbox clicked'
if __name__ == "__main__":
root = tk.Tk()
myCheckList(root).grid(row=0,column=0,sticky=tk.W,padx=0,pady=0)
root.mainloop()
Found it, after much wrestling and experimenting. It turns out that the trace works perfectly when I add a couple of lines to the class's __init__:
self.status = []
...and then, inside the loop...
self.status.append((cb,cbv))
...which tells me that garbage collection is the culprit. By creating a list and storing the object references in it, they couldn't be garbage-collected and so the .trace remains effective.
First off, you should prepend self. to cbv and cb within the FOR cycle.
Secondly, even then it is going to work only for the very last checkbox, because with each iteration you overwrite the variable cbv again and again.
As a workaround I used a list of vaiables (self.li) generated one step before the cycle. This way you can link each checkbox to its own variable:
self.li = ['cbv' + str(i) for i in range(100)]
for i in range(100):
self.li[i] = tk.IntVar()
self.cb = tk.Checkbutton(self, background=basecolor,
variable=self.li[i],
text="Checkbutton #%s" % i)
self.li[i].trace('w', self._cbWasClicked)
self.canvas.create_window(5,20*i+5,anchor=tk.NW,window=self.cb)
...
This code worked fine for me.
You will then need to identify each checkbox somehow. You can do it using the internal variable name which is passed as the first param to the callback function in the trace method (What are the arguments to Tkinter variable trace method callbacks?):
def _cbWasClicked(self, name, *args):
print('checkbox %s clicked:' % name)
In the output you'll get something like this:
checkbox PY_VAR10 clicked:
checkbox PY_VAR99 clicked:
checkbox PY_VAR0 clicked:

Interrupting `while loop` with keyboard in Cython

I want to be able to interrupt a long function with cython, using the usual CTRL+C interrupt command.
My C++ long function is repeatedly called inside a while loop from Cython code, but I want to be able, during the loop, to send an "interrupt" and block the while loop.
The interrupt also should wait the longFunction() to finish, so that no data are lost or kept in unknown status.
This is one of my first implementation, which obviously doesn't work:
computed=0;
print "Computing long function..."
while ( computed==0 ):
try:
computed = self.thisptr.aLongFunction()
except (KeyboardInterrupt, SystemExit):
computed=1
print '\n! Received keyboard interrupt.\n'
break;
(p.s. self.thisptr is the pointer to the current class which implements aLongFunction() )
You should be able to do something like this:
import signal
class Test():
def __init__(self):
self.loop_finished = False
signal.signal(signal.SIGINT, self.abort_loop)
def abort_loop(self, signal, frame):
self.loop_finished = True
def go(self):
while not self.loop_finished:
print "Calculating"
# Do your calculations
# Once calcations are done, set self.loop_finished to True
print "Calculating over"
Test().go()
You can also use additional variables to keep track of whether the computation was manually aborted or not.
I am not a Python C-Api foo master, however this works, but maybe its not the best way:
cdef extern from "Python.h":
int PyErr_CheckSignals()
def test_interrupt():
cdef int i = 0
while i < 9999999999 and not PyErr_CheckSignals():
# do fancy stuff.
i += 1
Of course that is not asynchronous which is maybe possible but I do not know and this breaks the loop for any signal, not just Ctrl+C. Also maybe its better to not check signals every loop iteration, at least if what is done is very cheap.
You could call PyErr_Occurred, etc. if PyErr_CheckSignals did not return 0 and see what kind of Exception got raised to go specifically for KeybordInterrupt or certain kill signals. (Anyway, check the python C-Api for details there...)
If you are calling a cython cdef function inside the while loop you may be able to achieve this also if you add except *:
cdef function(...) except *:
pass
see also http://docs.cython.org/src/userguide/language_basics.html#error-return-values