Как я читаю данные мыши неблокирующим способом - PullRequest
0 голосов
/ 12 февраля 2019

Я внедряю процедуру отказоустойчивой передачи обслуживания в ROS и для этого использую скрипты python.Я использую оптический датчик от мыши, чтобы контролировать ускорение объекта, чтобы я мог определить, когда падает.Кажется, все работает нормально, но теперь я хочу дать ограничение процедуры мониторинга (скажем, 1000 раз), прежде чем объявить, что передача прошла успешно.Проблема в том, что функция чтения, которую я использую для мыши, застревает, если движение не обнаружено, следующая итерация не выполняется.Как я могу читать с устройства, не сталкиваясь с этой проблемой?

Вот код, который я использую для чтения с мыши:

def getMouseEvent():
    buf = file.read(3)
    x, y = struct.unpack( "bb", buf[1:] )  # <--- X and Y deltas.
    return [x , y]

Вот цикл, который я хочу реализовать

release_grasp()
rospy.loginfo( "Force detected -- Release mode active")
# If the object is falling regrasp it.      
detected= False
trials = 0
while (not(detected) and trials < 1000):
    trials = trials + 1
    rospy.loginfo ("Acc monitored for the" + str(trials) + "th time"
    if fall_test():
        cilindrical_grasp()
        rospy.loginfo("Fall detected -- Object regrasped")
        detected = True     
    rate.sleep()

Вывод, который я получаю, блокируетдо данной итерации, пока мышь не обнаружит какое-либо движение.

ОБНОВЛЕНИЕ: Вот полный код

#!/usr/bin/env python2
import rospy
import numpy  
import struct
from reflex_sf_msgs.msg import SFPose
from matteo.msg import force
from matteo.msg import acc

# Defining force treshold in each direction ( to be completed and tuned )


rospy.init_node('DetectionFail')
xt = 0.5
yt = xt
zt = 0.3
# For the future try to handle the initialization.
fx = None
fy = None
fz = None
ax = None
ay = None

rate = rospy.Rate(100) # <--- Rate Hz

#-----------------------------MOUSE-----------------------------------#
# Open the mouse device. To be sure if it is "mouse2" type in the terminal: cat     /proc/bus/input/devices, look for the device whose name is "Logitech optical USB mouse"     and get the name of the handler. If you need root permissions type: sudo chmod 777  /dev/input/(handler)
file = open ("/dev/input/mouse3" , "rb")

#Defining the function to read mouse deltas.
def getMouseEvent():
    buf = file.read(3);
x,y = struct.unpack( "bb", buf[1:] ); # <--- X and Y deltas.
    return [x , y]

#Defining the function to estimate the acceleraton.
def acc_comp():
    vx_old = 0 
    vy_old = 0
    vx_new = getMouseEvent()[0]
    vy_new = getMouseEvent()[1]
    x_acc = (vx_old - vx_new)*100
    y_acc = (vy_old - vy_new)*100
    vx_old = vx_new
    vy_old = vy_new
    return [x_acc , y_acc]

#---------------------------------------------------------------------#
#Defining function fall test
def fall_test():
    if ( acc_comp()[1] >= 3000 or acc_comp()[1] <= -3000 ):
        return True
    else:
        return False

#---------------------------------------------------------------------#

# Initialize hand publisher.
hand_pub = rospy.Publisher('/reflex_sf/command', SFPose, queue_size=1)
rospy.sleep(0.5)

#---------------------------------------------------------------------#

# Defining sferical grasp.
def cilindrical_grasp():
hand_pub.publish ( 2.5 , 2.5 , 2.5, 0)

#---------------------------------------------------------------------#

# Define release position.
def release_grasp():
    hand_pub.publish ( 2,  2 , 2 , 0)

#---------------------------------------------------------------------#

# Define test for the force measure
def force_treshold ( fx, fy , fz):  
    if ( fx > xt and fy > yt or fz > zt):
        return True
    else:
        return False    

#---------------------------------------------------------------------#
# Callback function to save the datas obtained by the force sensor
def callback_force(msg):
    global fx
    global fy
    global fz
    fx = msg.fx
    fy = msg.fy
    fz = msg.fz


    # Main loop.
    def main():
        #Apply the sferical grasp.
        rospy.loginfo("Applying grasp")
        cilindrical_grasp()
            while not(rospy.is_shutdown()): 

                 rospy.Subscriber("/Forces", force, callback_force )

                    if force_treshold ( fx , fy , fz ):
                          release_grasp()
                          rospy.loginfo( "Force detected -- Release mode active")
                          # If the object is falling regrasp it.        
                          detected= False
                          trials = 0
                          while (not(detected) and trials < 1000):
                              trials = trials +1 
                              if fall_test():
                                 cilindrical_grasp()
                                 rospy.loginfo("Fall detected -- Object regrasped")
                                 detected = True        
            rate.sleep()
    if rospy.is_shutdown() :
        break               

Вчера я вышел с этим кодом:

#!/usr/bin/env python
import struct
import rospy
from matteo.msg import acc
import struct
import os
import time

i = 0

# Mouse read with a non blocking structure, the problem is that does not provide the same       output as 
# mouse_clean.py, probably there is a problem with the unpacking or the reading.

while i < 1000:
        i += 1
        try:
            file = os.open("/dev/input/mouse0", os.O_RDONLY | os.O_NONBLOCK)
            time.sleep(0.1)
            buf = os.read(file , 3)
            x,y = struct.unpack( "bb", buf[1:] ) # <--- X and Y deltas.
            print ( "X:" +str ( x ) + "---" +"Y:" +str ( y ) )
        except  OSError as err:
            if err.errno == 11:
                print ( "No motion detected")
                continue
        os.close(file)

Работает нормально, если нет движения, сообщение распечатывается, но в случае движения вывод, который я получаю, сильно отличается от режима "ваниль".

...