Acrome-SMD Docs
All Acrome ProductsReferencesBlogCase StudiesContact Us
  • ACROME SMD
  • Electronics
    • 🔴SMD Red
      • Troubleshooting Guide
    • 🔵SMD Blue
    • 🟢SMD Green
    • Gateway Modules
      • Arduino Gateway Module
      • USB Gateway Module
    • Electrical Motors
      • Brushed DC Motors (BDC)
      • Stepper DC Motors (SDC)
      • Brushless DC Motor (BLDC)
      • Linear Actuator with Feedback – 75 lbs
    • Add-on Modules
      • Ambient Light Sensor Module
      • Button Module
      • Buzzer Module
      • IMU Module
      • Joystick Module
      • Potentiometer Module
      • Reflectance Sensor Module
      • RGB LED Module
      • Servo Module
      • Ultrasonic Distance Sensor Module
  • SMD Kits
    • Starter Kit
      • Basic Brushed DC motor Applications
    • Education Kit
    • Motion Kit
      • Differential Robot Projects
  • Software
    • Libraries
      • Python Library
      • Arduino Library
      • Java Library
      • Matlab Library
    • SMD UI
    • SMD Blockly
      • Introducing Customized Blockly Blocks
  • SMD Applications
    • Basics
      • Blink
      • Action - Reaction
      • Autonomous Lighting
      • Smart Doorbell
      • Security System
      • Distance Buzzer Warning
      • Distance Auto Stop
      • Smart Light Control
    • Interactive
      • Automatic Trash Bin
      • Radar
      • Chrome Dino Game Player
      • Play Chrome Dino Game With Joystick
      • Snake Game With Joystick
      • Pan-Tilt with Joystick Module
      • Joystick Mouse Control
      • Rev Up the Engine
      • Motor Rotation Based on Turn Input Value
      • Basic Motor Speed Control Application
      • Basic Motor Control Application Using PWM Input
      • Basic Motor Position Control Application
      • Basic Motor Torque Control Application
      • Motor Rotation Based on Joystick Counting
    • Robotics
      • Mouse Cursor Tracker Motion Robot
      • Waypoint tracker robot
      • Braitenberg Robot
      • Line-Follower Robot
      • Object Tracking Robot
      • Teleoperation Robot
      • Obstacle Avoidance Robot
      • ESP32 Wireless Controlled Mobile Robot
  • AI
    • Groq Chatbot-Controlled Robot
  • Mechanics
    • Building Set
      • Plates
        • 2x2 Plate Package
        • 2x3 120° Plate Package
        • 3x3 Plate Package
        • 3x5 Plate Package
        • 3x9 Plate Package
        • 11x19 Plate
        • 9x19 Plate
        • 5x19 Plate
        • 3x19 Plate
        • 9x11 Plate
        • 5x13 Plate
      • Joints
        • 60° Joint Package
        • 90° Joint Package
        • 120° Joint Package
        • Slot Joint M2 Package
        • Slot Joint M3 Package
        • U Joint Package
      • Mounts
        • Add-on Mount Package
        • Motor L Mount Package
        • Pan-Tilt Package
      • Wheels
        • Ball Wheel Package
        • Caster Wheel Package
        • Wheel Package
      • Cables
        • Power Cable 10 cm Package
        • Power Cable 20 cm Package
        • Power Cable 35 cm Package
        • RJ-11 Cable 7.5 cm Package
        • RJ-11 Cable 20 cm Package
        • RJ-11 Cable 35 cm Package
        • RJ-45 Cable 7.5 cm Package
        • RJ-45 Cable 20 cm Package
        • RJ-45 Cable 35 cm Package
      • Fasteners
        • M2x5 Allen Hex Screw Package
        • M3x6 Allen Hex Screw Package
        • M3x8 Allen Hex Screw Package
        • M3 Hex Nut Package
  • Help
    • Manual
    • Shops
    • Reach Us
Powered by GitBook
On this page
  1. SMD Kits
  2. Motion Kit
  3. Differential Robot Projects

Teleoperation Robot

Last updated 1 month ago

The Teleoperation Robot allows users to control a robot remotely using a variety of input methods such as a joystick, keyboard, or even a mobile application. This project is designed to enhance human-robot interaction, making it ideal for remote inspection, assistance, and industrial automation.

Key Features:

  • Real-Time Remote Control: Operate the robot from a distance with low-latency response.

  • Multiple Control Interfaces: Supports joysticks, keyboards, and wireless controllers.

  • Live Data Feedback: Real-time sensor data monitoring for better decision-making.

  • Versatile Applications: Used in hazardous environments, remote assistance, and exploration.

code

from pynput import keyboard
import time
from smd.red import *
from serial.tools.list_ports import comports
from platform import system

class PIDController:

    def __init__(self, kp, ki, kd):
        self.kp = kp
        self.ki = ki
        self.kd = kd
        self.previous_error = 0
        self.integral = 0

    def calculate(self, error, delta_time):
        self.integral += error * delta_time
        derivative = (error - self.previous_error) / delta_time if delta_time > 0 else 0
        output = (self.kp * error) + (self.ki * self.integral) + (self.kd * derivative)
        self.previous_error = error
        return max(min(output, 100), -100)  
    
    def USB_Port():
        ports = list(comports())
        usb_names = {
            "Windows": ["USB Serial Port"],
            "Linux": ["/dev/ttyUSB"],
            "Darwin": [
                "/dev/tty.usbserial",
                "/dev/tty.usbmodem",
                "/dev/tty.SLAB_USBtoUART",
                "/dev/tty.wchusbserial",
                "/dev/cu.usbserial",
            ]
        }
        os_name = system()
        if ports:
            for port, desc, hwid in sorted(ports):
                if any(name in port or name in desc for name in usb_names.get(os_name, [])):
                    print("Connected!")
                    return port
            print("Available ports:")
            for port, desc, hwid in ports:
                print(f"Port: {port}, Description: {desc}, HWID: {hwid}")
        else:
            print("No ports detected!")
        return None
    
    def teleoperate_smd():
        print("Use W/A/S/D to control the robot. Press Q to quit.")
    
        port = USB_Port()
        if not port:
            print("No suitable port found. Exiting...")
            return
    
        try:
            smd = Master(port)
            smd.attach(Red(0))  # Left motor (ID 0)
            smd.attach(Red(1))  # Right motor (ID 1)
            
            smd.enable_torque(0, 1)
            smd.enable_torque(1, 1)
    
            left_pid = PIDController(kp=24.96, ki=0.00, kd=19.10)
            right_pid = PIDController(kp=46.97, ki=0.00, kd=18.96)
    
            base_speed = 100  
            turning_speed = 100  # Speed for turning
            last_time = time.time()
    
            def on_press(key):
                nonlocal last_time
    
                try:
                    # Calculate time difference
                    current_time = time.time()
                    delta_time = current_time - last_time
                    last_time = current_time
    
                    if hasattr(key, 'char'):
                        if key.char == 'w':  # Move forward
                            print("Move Forward")
                            error = base_speed
                            left_speed = left_pid.calculate(error, delta_time)
                            right_speed = right_pid.calculate(error, delta_time)
                            # Send commands to both motors simultaneously
                            smd.set_duty_cycle(0, -left_speed)  # Left motor forward
                            smd.set_duty_cycle(1, right_speed)  # Right motor forward
                        elif key.char == 's':  # Move backward
                            print("Move Backward")
                            error = -base_speed
                            left_speed = left_pid.calculate(error, delta_time)
                            right_speed = right_pid.calculate(error, delta_time)
                            # Send commands to both motors simultaneously
                            smd.set_duty_cycle(0, -left_speed)  # Left motor backward
                            smd.set_duty_cycle(1, right_speed)  # Right motor backward
                        elif key.char == 'a':  # Turn left
                            print("Turn Left")
                            # Send commands to both motors simultaneously
                            smd.set_duty_cycle(0, 0)  # Left motor stopped
                            smd.set_duty_cycle(1, turning_speed)  # Right motor forward
                        elif key.char == 'd':  # Turn right
                            print("Turn Right")
                            # Send commands to both motors simultaneously
                            smd.set_duty_cycle(0, -turning_speed)  # Left motor forward
                            smd.set_duty_cycle(1, 0)  # Right motor stopped
                        elif key.char == 'q':  # Quit
                            print("Exiting...")
                            return False
                except AttributeError:
                    pass

        def on_release(key):
            # Stop both motors simultaneously
            smd.set_duty_cycle(0, 0)
            smd.set_duty_cycle(1, 0)

        # Start keyboard listener
        with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
            listener.join()

    except Exception as e:
        print(f"Error: {e}")
    finally:
        # Stop both motors simultaneously during cleanup
        smd.set_duty_cycle(0, 0)
        smd.set_duty_cycle(1, 0)
        smd.enable_torque(0, 0)
        smd.enable_torque(1, 0)
        smd.close()
        print("SMD connection closed.")

teleoperate_smd()
Discover More About the Teleoperation Robot