A differential drive robot is controlled by varying the relative speed and direction of its two wheels. When both wheels rotate at the same speed, the robot moves forward or backward. When one wheel rotates faster than the other, or one wheel is stationary, the robot turns. This makes differential drive robots ideal for tasks that require precise navigation in constrained environments.
The Braitenberg Robot is inspired by Valentino Braitenberg's concept of simple vehicles exhibiting lifelike behaviors. This robot uses two light sensors and two motors that allow it to either chase or flee from light, depending on its configuration (e.g., 'love' or 'aggression' modes).
The Line-Follower Robot autonomously follows a predefined line, using reflectance sensors to detect lines on a surface. It employs a PID algorithm to determine motor control for smooth and precise line following.
This robot demonstrates AI-powered object tracking using a camera to capture real-time video of the environment. AI algorithms process the video to identify and track specific objects, enabling the robot to move toward and follow them.
Key SMD Products Used:
SMD Pan-Tilt Kit
2x 100 RPM Brushed DC Motors with Encoders.
Additional Items Required:
Hardware: NVIDIA Jetson Nano for AI computation, Battery Pack, Camera (Webcam works)
Software: Example Python code using SMD Python Library and Mobilnet SSD library
4. Teleoperating SMD Motion Kit Using Keyboard
One of the simplest ways to control a differential drive robot is through teleoperation. Using the keyboard, you can manually control the robot's movement.
Teleoperation is a technology that enables the remote control of a device or system. It is particularly useful in scenarios where robotic systems need to be operated from a distance. Examples include surgeons controlling robotic arms during remote surgeries or guiding robots in hazardous environments. This technology combines human skills and decision-making capabilities with robotic systems, enhancing safety and enabling the execution of complex tasks.
Below is an example Python script for teleoperating a differential drive robot:
from pynput import keyboardimport timefrom smd.red import*from serial.tools.list_ports import comportsfrom platform import systemclassPIDController:def__init__(self,kp,ki,kd): self.kp = kp self.ki = ki self.kd = kd self.previous_error =0 self.integral =0defcalculate(self,error,delta_time): self.integral += error * delta_time derivative = (error - self.previous_error) / delta_time if delta_time >0else0 output = (self.kp * error) + (self.ki * self.integral) + (self.kd * derivative) self.previous_error = errorreturnmax(min(output, 100), -100)defUSB_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 insorted(ports):ifany(name in port or name in desc for name in usb_names.get(os_name, [])):print("Connected!")return portprint("Available ports:")for port, desc, hwid in ports:print(f"Port: {port}, Description: {desc}, HWID: {hwid}")else:print("No ports detected!")returnNonedefteleoperate_smd():print("Use W/A/S/D to control the robot. Press Q to quit.") port =USB_Port()ifnot port:print("No suitable port found. Exiting...")returntry: 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()defon_press(key):nonlocal last_timetry:# Calculate time difference current_time = time.time() delta_time = current_time - last_time last_time = current_timeifhasattr(key, 'char'):if key.char =='w':# Move forwardprint("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 forwardelif key.char =='s':# Move backwardprint("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 backwardelif key.char =='a':# Turn leftprint("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 forwardelif key.char =='d':# Turn rightprint("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 stoppedelif key.char =='q':# Quitprint("Exiting...")returnFalseexceptAttributeError:passdefon_release(key):# Stop both motors simultaneously smd.set_duty_cycle(0, 0) smd.set_duty_cycle(1, 0)# Start keyboard listenerwith keyboard.Listener(on_press=on_press, on_release=on_release)as listener: listener.join()exceptExceptionas 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()