Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ModuleNotFoundError: No module named 'termios' #27

Open
shivamk160402 opened this issue Aug 22, 2021 · 3 comments
Open

ModuleNotFoundError: No module named 'termios' #27

shivamk160402 opened this issue Aug 22, 2021 · 3 comments

Comments

@shivamk160402
Copy link

I am using ros on windows (not on wsl ) and want to use teleop twist keyboard package to control the robot, and it is showing error ModuleNotFoundError: No module named 'termios' i searched on google and found that termios in not for windows so what can do to solve this problem, also while searching online i found termiwin, should I use that, if yes how

@trainman419
Copy link
Contributor

Hrm... if the termios python library isn't available on Windows, then it will either need to be made optional or replaced with an equivalent python library for Linux. termiwin is a C library, so it can't be used.

I've made a branch named optional_termios which makes the import of termios optional. I'm not sure if this will work appropriately but it may give some idea about where additional changes need to be made.

Here's the teleop_twist_keyboard.py on that branch: https://github.com/ros-teleop/teleop_twist_keyboard/blob/optional_termios/teleop_twist_keyboard.py

and here is the diff showing the changes that I made: https://github.com/ros-teleop/teleop_twist_keyboard/compare/optional_termios

I don't have windows or the time to test this, but if you are able to confirm that it works for you or update teleop_twist_keyboard and submit a PR which makes it work on Windows, I will gladly accept those changes and release a new version.

Good luck!

@shivamk160402
Copy link
Author

@trainman419 I wasn't able to get complete replacement for termios and tty but i found msvcrt a good replacement, it records a new key input every time, it is working fine for me but don't weather the code is capable of publishing here it is.
`#!/usr/bin/env python

from future import print_function

import threading

import roslib; roslib.load_manifest('teleop_twist_keyboard')
import rospy

from geometry_msgs.msg import Twist

have_msvcrt = False
try:
import msvcrt
have_msvcrt = True
except ImportError:
pass
import sys, select
have_termios = False
try:
import termios,tty
have_termios = True
except ImportError:
pass

msg = """
Reading from the keyboard and Publishing to Twist!

Moving around:
u i o
j k l
m , .

For Holonomic mode (strafing), hold down the shift key:

U I O
J K L
M < >

t : up (+z)
b : down (-z)

anything else : stop

q/z : increase/decrease max speeds by 10%
w/x : increase/decrease only linear speed by 10%
e/c : increase/decrease only angular speed by 10%

CTRL-C to quit
"""

moveBindings = {
'i':(1,0,0,0),
'o':(1,0,0,-1),
'j':(0,0,0,1),
'l':(0,0,0,-1),
'u':(1,0,0,1),
',':(-1,0,0,0),
'.':(-1,0,0,1),
'm':(-1,0,0,-1),
'O':(1,-1,0,0),
'I':(1,0,0,0),
'J':(0,1,0,0),
'L':(0,-1,0,0),
'U':(1,1,0,0),
'<':(-1,0,0,0),
'>':(-1,-1,0,0),
'M':(-1,1,0,0),
't':(0,0,1,0),
'b':(0,0,-1,0),
}

speedBindings={
'q':(1.1,1.1),
'z':(.9,.9),
'w':(1.1,1),
'x':(.9,1),
'e':(1,1.1),
'c':(1,.9),
}

class PublishThread(threading.Thread):
def init(self, rate):
super(PublishThread, self).init()
self.publisher = rospy.Publisher('cmd_vel', Twist, queue_size = 1)
self.x = 0.0
self.y = 0.0
self.z = 0.0
self.th = 0.0
self.speed = 0.0
self.turn = 0.0
self.condition = threading.Condition()
self.done = False

    # Set timeout to None if rate is 0 (causes new_message to wait forever
    # for new data to publish)
    if rate != 0.0:
        self.timeout = 1.0 / rate
    else:
        self.timeout = None

    self.start()

def wait_for_subscribers(self):
    i = 0
    while not rospy.is_shutdown() and self.publisher.get_num_connections() == 0:
        if i == 4:
            print("Waiting for subscriber to connect to {}".format(self.publisher.name))
        rospy.sleep(0.5)
        i += 1
        i = i % 5
    if rospy.is_shutdown():
        raise Exception("Got shutdown request before subscribers connected")

def update(self, x, y, z, th, speed, turn):
    self.condition.acquire()
    self.x = x
    self.y = y
    self.z = z
    self.th = th
    self.speed = speed
    self.turn = turn
    # Notify publish thread that we have a new message.
    self.condition.notify()
    self.condition.release()

def stop(self):
    self.done = True
    self.update(0, 0, 0, 0, 0, 0)
    self.join()

def run(self):
    twist = Twist()
    while not self.done:
        self.condition.acquire()
        # Wait for a new message or timeout.
        self.condition.wait(self.timeout)

        # Copy state into twist message.
        twist.linear.x = self.x * self.speed
        twist.linear.y = self.y * self.speed
        twist.linear.z = self.z * self.speed
        twist.angular.x = 0
        twist.angular.y = 0
        twist.angular.z = self.th * self.turn

        self.condition.release()

        # Publish.
        self.publisher.publish(twist)

    # Publish stop message when thread exits.
    twist.linear.x = 0
    twist.linear.y = 0
    twist.linear.z = 0
    twist.angular.x = 0
    twist.angular.y = 0
    twist.angular.z = 0
    self.publisher.publish(twist)

def getKey(key_timeout):
if have_termios:
tty.setraw(sys.stdin.fileno())
rlist, _, _ = select.select([sys.stdin], [], [], key_timeout)
if rlist:
key = sys.stdin.read(1)
else:
key = ''
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
elif have_msvcrt:
key = msvcrt.getch()
key = key.decode("utf-8")
return key

def vels(speed, turn):
return "currently:\tspeed %s\tturn %s " % (speed,turn)

if name=="main":
if have_termios:
settings = termios.tcgetattr(sys.stdin)

rospy.init_node('teleop_twist_keyboard')

speed = rospy.get_param("~speed", 0.5)
turn = rospy.get_param("~turn", 1.0)
repeat = rospy.get_param("~repeat_rate", 0.0)
key_timeout = rospy.get_param("~key_timeout", 0.0)
if key_timeout == 0.0:
    key_timeout = None

pub_thread = PublishThread(repeat)

x = 0
y = 0
z = 0
th = 0
status = 0

try:
    pub_thread.wait_for_subscribers()
    pub_thread.update(x, y, z, th, speed, turn)

    print(msg)
    print(vels(speed,turn))
    while(1):
        key = getKey(key_timeout)
        if key in moveBindings.keys():
            x = moveBindings[key][0]
            y = moveBindings[key][1]
            z = moveBindings[key][2]
            th = moveBindings[key][3]
        elif key in speedBindings.keys():
            speed = speed * speedBindings[key][0]
            turn = turn * speedBindings[key][1]

            print(vels(speed,turn))
            if (status == 14):
                print(msg)
            status = (status + 1) % 15
        else:
            # Skip updating cmd_vel if key timeout and robot already
            # stopped.
            if key == '' and x == 0 and y == 0 and z == 0 and th == 0:
                continue
            x = 0
            y = 0
            z = 0
            th = 0
            if (key == '\x03'):
                break

        pub_thread.update(x, y, z, th, speed, turn)

except Exception as e:
    print(e)

finally:
    pub_thread.stop()
    if have_termios:
        termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)

`

@trainman419
Copy link
Contributor

Nice work!
You can run rostopic echo /cmd_vel in another terminal to see the messages that teleop_twist_keyboard is publishing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants