Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Hi,

I found a working solution - must have been error on my end.

Attached code will broadcast the XY mouse position and speed as JSON on topic 'chatter':

{"dt": 0.25, "dx": 2, "dy": 10, "mouse": 1, "xpos": 391, "ypos": -103}

When invoking the mouseMsg.py you can select which mouse # you want to read and what is the readout frequency.

Thanks

Jan

#!/usr/bin/env python
''' 
Software License Agreement (BSD License)
Copyright (c) 2008, Willow Garage, Inc.
 Modified by Jan Balewski, December 2016

Simple talker modified to broadcast mouse relative position 
that published JSON as std_msgs/Strings messages
to the 'chatter' topic
'''

import sys,os
import json
import subprocess
import rospy
from std_msgs.msg import String

#----------------------
def onFailedStart(myNo):
    print 
    print('Mouse %d data access failed. Few tips:'%myNo)
    task = subprocess.Popen("cat /proc/bus/input/devices", shell=True, stdout=subprocess.PIPE)
    data = task.stdout.read()
    assert task.wait() == 0
    m=0
    for line in data.decode('utf-8').split("\n"):
        #    print line
        if "H: Handlers=mouse" in line:
            #print line
            lL=line.split()
            #print lL[1]
            msNo=int(lL[1][-1])
            devName='/dev/input/mouse%d'%msNo
            stats = os.stat(devName)

            print 'see: ',devName, ' access=',oct(stats.st_mode& 0777)

    print ' try:   sudo chmod a+x ',devName 
    print 
    print 'use:  mouseMsg.py [mouseNo] [rate/Hz]'

#----------------------
def mouseState(myNo):
    global fm,readRate,xpos,ypos
    # read from the file. ord() converts char to integer
    state = ord(fm.read(1))
    dx = ord(fm.read(1))
    dy = ord(fm.read(1))

    #convert bits in 'state' in to an array 'mouse_state'
    mouse_state = [(state & (1 << i)) >> i for i in xrange(8)]

    # if mouse moving to the left. dx must be a negative value
    if mouse_state[4] == 1:
        dx = dx - 256    # convert 2's complement negative value

    # if mouse moving down
    if mouse_state[5] == 1:
        dy = dy - 256

    if (mouse_state[6] == 1) or (mouse_state[7]==1):
        print "Overflow!"

    # update the position
    xpos += dx
    ypos += dy

    out={"mouse":myNo,'dx':dx,'dy':dy,'xpos':xpos,'ypos':ypos}

    return out

#----------------------
def mouseMsg(myNo):
    global fm,readRate
    myName='devMouse%d'%myNo
    pub = rospy.Publisher('chatter', String, queue_size=10)
    rospy.init_node(myName, anonymous=True)
    rateHn = rospy.Rate(readRate) 
    dt=1/float(readRate)

    rospy.loginfo(myName+' found, move it , ctrl\ to abort.')
    k=0
    while not rospy.is_shutdown():
        k+=1
        outD=mouseState(myNo)
        outD['dt']=dt
        outStr=json.dumps(outD,sort_keys=True)
        if k%50==0:
            rospy.loginfo(outStr+' k=%d'%k)
        pub.publish(outStr)
        rateHn.sleep()

if __name__ == '__main__':
    global fm,readRate,xpos,ypos
    myNo=0
    readRate=10  # Hz
    (xpos,ypos)=(0,0)

    if len(sys.argv)>=2:
        myNo=int(sys.argv[1])
    if len(sys.argv)==3:
        readRate=int(sys.argv[2])
        assert(readRate>0)
        assert(readRate<20)

    devName='/dev/input/mouse%d'%myNo


    try:
        fm = open(devName, 'rb')
    except:
        onFailedStart(myNo)
        exit(1)

    try:
        mouseMsg(myNo)
    except rospy.ROSInterruptException:
        pass

Hi,

I found a working solution - must have been error on my end.

Attached code will broadcast the XY mouse position and speed as JSON on topic 'chatter':

{"dt": 0.25, "dx": 2, "dy": 10, "mouse": 1, "xpos": 391, "ypos": -103}

When invoking the mouseMsg.py you can select which mouse # you want to read and what is the readout frequency.

Thanks

Jan

#!/usr/bin/env python
''' 
Software License Agreement (BSD License)
Copyright (c) 2008, Willow Garage, Inc.
 Modified by Jan Balewski, December 2016

Simple talker modified to broadcast mouse relative position 
that published JSON as std_msgs/Strings messages
to the 'chatter' topic
'''

import sys,os
import json
import subprocess
import rospy
from std_msgs.msg import String

#----------------------
def onFailedStart(myNo):
    print 
    print('Mouse %d data access failed. Few tips:'%myNo)
    task = subprocess.Popen("cat /proc/bus/input/devices", shell=True, stdout=subprocess.PIPE)
    data = task.stdout.read()
    assert task.wait() == 0
    m=0
    for line in data.decode('utf-8').split("\n"):
        #    print line
        if "H: Handlers=mouse" in line:
            #print line
            lL=line.split()
            #print lL[1]
            msNo=int(lL[1][-1])
            devName='/dev/input/mouse%d'%msNo
            stats = os.stat(devName)

            print 'see: ',devName, ' access=',oct(stats.st_mode& 0777)

    print ' try:   sudo chmod a+x a+r ',devName 
    print 
    print 'use:  mouseMsg.py [mouseNo] [rate/Hz]'

#----------------------
def mouseState(myNo):
    global fm,readRate,xpos,ypos
    # read from the file. ord() converts char to integer
    state = ord(fm.read(1))
    dx = ord(fm.read(1))
    dy = ord(fm.read(1))

    #convert bits in 'state' in to an array 'mouse_state'
    mouse_state = [(state & (1 << i)) >> i for i in xrange(8)]

    # if mouse moving to the left. dx must be a negative value
    if mouse_state[4] == 1:
        dx = dx - 256    # convert 2's complement negative value

    # if mouse moving down
    if mouse_state[5] == 1:
        dy = dy - 256

    if (mouse_state[6] == 1) or (mouse_state[7]==1):
        print "Overflow!"

    # update the position
    xpos += dx
    ypos += dy

    out={"mouse":myNo,'dx':dx,'dy':dy,'xpos':xpos,'ypos':ypos}

    return out

#----------------------
def mouseMsg(myNo):
    global fm,readRate
    myName='devMouse%d'%myNo
    pub = rospy.Publisher('chatter', String, queue_size=10)
    rospy.init_node(myName, anonymous=True)
    rateHn = rospy.Rate(readRate) 
    dt=1/float(readRate)

    rospy.loginfo(myName+' found, move it , ctrl\ to abort.')
    k=0
    while not rospy.is_shutdown():
        k+=1
        outD=mouseState(myNo)
        outD['dt']=dt
        outStr=json.dumps(outD,sort_keys=True)
        if k%50==0:
            rospy.loginfo(outStr+' k=%d'%k)
        pub.publish(outStr)
        rateHn.sleep()

if __name__ == '__main__':
    global fm,readRate,xpos,ypos
    myNo=0
    readRate=10  # Hz
    (xpos,ypos)=(0,0)

    if len(sys.argv)>=2:
        myNo=int(sys.argv[1])
    if len(sys.argv)==3:
        readRate=int(sys.argv[2])
        assert(readRate>0)
        assert(readRate<20)

    devName='/dev/input/mouse%d'%myNo


    try:
        fm = open(devName, 'rb')
    except:
        onFailedStart(myNo)
        exit(1)

    try:
        mouseMsg(myNo)
    except rospy.ROSInterruptException:
        pass

Hi,

I found a working solution - must have been error on my end.

Attached code will broadcast the XY mouse position and speed as JSON on topic 'chatter':

{"dt": 0.25, "dx": 2, "dy": 10, "mouse": 1, "xpos": 391, "ypos": -103}

When invoking the mouseMsg.py you can select which mouse # you want to read and what is the readout frequency.

Thanks

Jan

#!/usr/bin/env python
''' 
Software License Agreement (BSD License)
Copyright (c) 2008, Willow Garage, Inc.
 Modified by Author: Jan Balewski, December 2016

Simple talker modified to broadcast Talker broadcasts mouse relative position 
that position, 
published as JSON as using std_msgs/Strings messages
message
to the 'chatter' topic
'''

import sys,os
import json
import subprocess
import rospy
from std_msgs.msg import String

#----------------------
def onFailedStart(myNo):
    print 
    print('Mouse %d data access failed. Few tips:'%myNo)
    task = subprocess.Popen("cat /proc/bus/input/devices", shell=True, stdout=subprocess.PIPE)
    data = task.stdout.read()
    assert task.wait() == 0
    m=0
    for line in data.decode('utf-8').split("\n"):
        #    print line
        if "H: Handlers=mouse" in line:
            #print line
            lL=line.split()
            #print lL[1]
            msNo=int(lL[1][-1])
            devName='/dev/input/mouse%d'%msNo
            stats = os.stat(devName)

            print 'see: ',devName, ' access=',oct(stats.st_mode& 0777)

    print ' try:   sudo chmod a+r ',devName 
    print 
    print 'use:  mouseMsg.py [mouseNo] [rate/Hz]'

#----------------------
def mouseState(myNo):
    global fm,readRate,xpos,ypos
    # read from the file. ord() converts char to integer
    state = ord(fm.read(1))
    dx = ord(fm.read(1))
    dy = ord(fm.read(1))

    #convert bits in 'state' in to an array 'mouse_state'
    mouse_state = [(state & (1 << i)) >> i for i in xrange(8)]

    # if mouse moving to the left. dx must be a negative value
    if mouse_state[4] == 1:
        dx = dx - 256    # convert 2's complement negative value

    # if mouse moving down
    if mouse_state[5] == 1:
        dy = dy - 256

    if (mouse_state[6] == 1) or (mouse_state[7]==1):
        print "Overflow!"

    # update the position
    xpos += dx
    ypos += dy

    out={"mouse":myNo,'dx':dx,'dy':dy,'xpos':xpos,'ypos':ypos}

    return out

#----------------------
def mouseMsg(myNo):
    global fm,readRate
    myName='devMouse%d'%myNo
    pub = rospy.Publisher('chatter', String, queue_size=10)
    rospy.init_node(myName, anonymous=True)
    rateHn = rospy.Rate(readRate) 
    dt=1/float(readRate)

    rospy.loginfo(myName+' found, move it , ctrl\ to abort.')
    k=0
    while not rospy.is_shutdown():
        k+=1
        outD=mouseState(myNo)
        outD['dt']=dt
        outStr=json.dumps(outD,sort_keys=True)
        if k%50==0:
            rospy.loginfo(outStr+' k=%d'%k)
        pub.publish(outStr)
        rateHn.sleep()

if __name__ == '__main__':
    global fm,readRate,xpos,ypos
    myNo=0
    readRate=10  # Hz
    (xpos,ypos)=(0,0)

    if len(sys.argv)>=2:
        myNo=int(sys.argv[1])
    if len(sys.argv)==3:
        readRate=int(sys.argv[2])
        assert(readRate>0)
        assert(readRate<20)

    devName='/dev/input/mouse%d'%myNo


    try:
        fm = open(devName, 'rb')
    except:
        onFailedStart(myNo)
        exit(1)

    try:
        mouseMsg(myNo)
    except rospy.ROSInterruptException:
        pass