I. Preface
NAO robots have been in contact for more than a year, during which many programs have been developed.
First, NAO robot face recognition and path planning in complex indoor environment are done.
Later, he participated in the NAO Robot Golf Tournament and developed a complete framework for the NAO Robot Golf Tournament, and provided the source code to the organizers.
On this basis, it also helps organizers to develop a NAO robot relay program framework. The first version is the robot's message transmission through Socket communication, which is also mentioned in this chapter. The second version is the robot's information extraction through machine vision.
Now let's talk about socket communication.
TCP server:
1 Create sockets, bind sockets to local IP and ports
# socket.socket(socket.AF_INET,socket.SOCK_STREAM) , s.bind()
2 Start listening on connection # s.listen()
3 Enter the loop and continue to accept client connection requests #s.accept()___________.
4 Then receive the incoming data and send it to the other party # s. recv (), s. sendall ()
5 Close the socket # s.close()
TCP client:
1 Create sockets to connect to remote addresses
# socket.socket(socket.AF_INET,socket.SOCK_STREAM) , s.connect()
Send and receive data after connection# s.sendall(), s.recv()
Close the socket # s.close()
For NAO robots, there is nothing more than a server and a client. The code is as follows:
client.py
#-*- coding: utf-8 -*-
###########################################################
# > Description: Remote Control - Client
# Send instructions to the server to view the server receipt message.
###########################################################
#! /usr/bin/env python
import argparse
from naoqi import ALProxy
import socket
import time
LISTEN_PORT = 8001 # Server listening port
# command
COMMAND_DISCONNECT = 'DISCONNECT'
COMMAND_HEADYAW = 'HEADYAW' # Around the head
COMMAND_HEADPITCH = 'HEADPITCH' # Head up and down
# flag
CONNECT = False
def main(robot_IP, robot_PORT=9559):
# ----------> Connect to socket server listening port
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((robot_IP, LISTEN_PORT))
time.sleep(2)
CONNECT = True
while CONNECT == True:
# Input instruction
command = raw_input("Command code:")
# socket sends instructions
sock.send(command)
if command == COMMAND_HEADYAW or command == COMMAND_HEADPITCH:
value = raw_input("Value:")
sock.send(value)
# socket accepts the return message
buf = sock.recv(1024)
print buf
if command == COMMAND_DISCONNECT:
CONNECT = False
sock.close() # Disconnect socket from server
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--ip", type=str, default="192.168.1.100", help="Robot ip address")
parser.add_argument("--port", type=int, default=9559, help="Robot port number")
args = parser.parse_args()
# Executing main function
main(args.ip, args.port)
server.py
#! /usr/bin/env python
#-*- coding: utf-8 -*-
###########################################################
# > Description: Remote Control - Server Side
# Accept the instructions from the client and perform the corresponding functions.
###########################################################
import argparse
from naoqi import ALProxy
import socket
import sys # sys.exit() exits main function
import almath # Almath. TO_RAD
import thread # Multithreading
import time # Delay function time.sleep(1)
LISTEN_PORT = 8001 # Server listening port
# Command Definition
COMMAND_WAKEUP = 'WAKEUP'
COMMAND_REST = 'REST'
COMMAND_FORWARD = 'FORWARD'
COMMAND_BACK = 'BACK'
COMMAND_LEFT = 'LEFT'
COMMAND_RIGHT = 'RIGHT'
COMMAND_STOP = 'STOP'
COMMAND_TURNLEFT = 'TURNLEFT'
COMMAND_TURNRIGHT = 'TURNRIGHT'
COMMAND_DISCONNECT = 'DISCONNECT'
COMMAND_SENSOR = 'SENSOR'
COMMAND_HEADYAW = 'HEADYAW' # Around the head
COMMAND_HEADPITCH = 'HEADPITCH' # Head up and down
# flag
CONNECT = False # Client Connection Flag
SENSOR = False # Sensors monitor Flag, and threads send data regularly for True.
# Global variables for use by other functions
ROBOT_IP = '192.168.1.100'
ROBOT_PORT = 9559
connection = None
battery = None
memory = None
def main(robot_IP, robot_PORT=9559):
global ROBOT_IP
global ROBOT_PORT
ROBOT_IP = robot_IP
ROBOT_PORT = robot_PORT
# ----------> Connect to robot <----------
tts = ALProxy("ALTextToSpeech", robot_IP, robot_PORT)
motion = ALProxy("ALMotion", robot_IP, robot_PORT)
posture = ALProxy("ALRobotPosture", robot_IP, robot_PORT)
global memory
memory = ALProxy("ALMemory", robot_IP, robot_PORT)
leds = ALProxy("ALLeds", robot_IP, robot_PORT)
global battery
battery = ALProxy("ALBattery", ROBOT_IP, ROBOT_PORT)
autonomous = ALProxy("ALAutonomousLife", robot_IP, robot_PORT)
autonomous.setState("disabled") # turn ALAutonomousLife off
# Open the socket server listening port
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((robot_IP, LISTEN_PORT))
sock.listen(10)
try:
while True: # Waiting for client connection, single thread listening for single client
global connection
connection,address = sock.accept()
CONNECT = True
while CONNECT == True:
try:
#connection.settimeout(10)
# Server accepts instructions
buf = connection.recv(1024)
print "get:[", buf, "]"
# Perform different operations according to the received commands
if buf == COMMAND_WAKEUP:
if motion.robotIsWakeUp() == False:
motion.post.wakeUp()
connection.send("Robot Motion: [ Wakeup ]\r")
elif buf == COMMAND_REST:
if motion.robotIsWakeUp() == True:
motion.post.rest()
connection.send("Robot Motion: [ Rest ]\r")
elif buf == COMMAND_FORWARD:
if motion.robotIsWakeUp() == False:
motion.post.wakeUp()
connection.send("Robot Motion: [ Wakeup ]\r")
motion.post.moveInit()
connection.send("Robot Motion: [ MoveInit ]\r")
#motion.post.moveTo(0.3, 0, 0)
motion.move(0.1,0,0) # Continuous walking at a fixed rate
connection.send("Robot Motion: [ Forward ]\r")
elif buf == COMMAND_BACK:
if motion.robotIsWakeUp() == False:
motion.post.wakeUp()
connection.send("Robot Motion: [ Wakeup ]\r")
motion.post.moveInit()
connection.send("Robot Motion: [ MoveInit ]\r")
#motion.post.moveTo(-0.1, 0, 0)
motion.move(-0.1,0,0)
connection.send("Robot Motion: [ Back ]\r")
elif buf == COMMAND_LEFT:
if motion.robotIsWakeUp() == False:
motion.post.wakeUp()
connection.send("Robot Motion: [ Wakeup ]\r")
motion.post.moveInit()
connection.send("Robot Motion: [ MoveInit ]\r")
#motion.post.moveTo(0, 0.1, 0)
motion.move(0,0.1,0)
connection.send("Robot Motion: [ Left ]\r")
elif buf == COMMAND_RIGHT:
if motion.robotIsWakeUp() == False:
motion.post.wakeUp()
connection.send("Robot Motion: [ Wakeup ]\r")
motion.post.moveInit()
connection.send("Robot Motion: [ MoveInit ]\r")
#motion.post.moveTo(0, -0.1, 0)
motion.move(0,-0.1,0)
connection.send("Robot Motion: [ Right ]\r")
elif buf == COMMAND_STOP:
motion.stopMove()
connection.send("Robot Motion: [ stop move ]\r")
elif buf == COMMAND_TURNRIGHT:
if motion.robotIsWakeUp() == False:
motion.post.wakeUp()
connection.send("Robot Motion: [ Wakeup ]\r")
motion.post.moveInit()
connection.send("Robot Motion: [ MoveInit ]\r")
motion.move(0, 0, -0.3)
connection.send("Robot Motion: [ turn right ]\r")
elif buf == COMMAND_TURNLEFT:
if motion.robotIsWakeUp() == False:
motion.post.wakeUp()
connection.send("Robot Motion: [ Wakeup ]\r")
motion.post.moveInit()
connection.send("Robot Motion: [ MoveInit ]\r")
motion.move(0, 0, 0.3)
connection.send("Robot Motion: [ turn left ]\r")
elif buf == COMMAND_DISCONNECT:
CONNECT = False
connection.send("disconnect from robot server.\r")
elif buf == COMMAND_HEADYAW:
# Head turning left and right (Yaw axis)
buf2 = connection.recv(1024) # Read Yaw values
print "yaw:", buf2
angles = (int(buf2) - 50)
motion.setStiffnesses("Head", 1.0)
motion.setAngles("HeadYaw", angles * almath.TO_RAD, 0.2) # Converting angles angle at 10% speed
connection.send("Robot Motion: [ head raw ]\r")
elif buf == COMMAND_HEADPITCH:
# Head up and down rotation (Pitch axis)
buf2 = connection.recv(1024) # Read Pitch values
print "pitch:", buf2
angles = (int(buf2) - 50) * 2
motion.setStiffnesses("Head", 1.0)
motion.setAngles("HeadPitch", angles * almath.TO_RAD, 0.2) # Converting angles angle at 10% speed
connection.send("Robot Motion: [ head pitch ]\r")
elif buf == COMMAND_SENSOR:
global SENSOR
if SENSOR == False:
# Open new threads and send sensor data regularly
SENSOR = True
thread.start_new_thread(sensor, (1,)) # 2nd arg must be a tuple
else:
# When COMMAND_SENSOR is sent the second time, the thread is closed
SENSOR = False # Set the identification bit and exit the thread itself after detection.
connection.send("Robot Motion: [ send sensor value ]\r")
else:
connection.send(buf + ": command not found\r")
except socket.timeout:
print 'time out'
connection.close() # Close the current socket connection and enter the next cycle
except KeyboardInterrupt: # CTRL+C, close the server-side program;
print ""
print "Interrupted by user, shutting down"
sys.exit(0)
def sensor(interval):
''' each interval Send sensor data once in seconds
'''
while SENSOR == True:
connection.send("BATTERY" + "#" + str(battery.getBatteryCharge()) + "\r")
connection.send("SONAR1" + "#" + str(memory.getData("Device/SubDeviceList/US/Left/Sensor/Value")) + "\r")
connection.send("SONAR2" + "#" + str(memory.getData("Device/SubDeviceList/US/Right/Sensor/Value")) + "\r")
# print "BATTERY" + "#" + str(battery.getBatteryCharge())
time.sleep(interval)
# SENSOR == False
thread.exit_thread()
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--ip", type=str, default="192.168.1.100", help="Robot ip address")
parser.add_argument("--port", type=int, default=9559, help="Robot port number")
args = parser.parse_args()
# Executing main function
main(args.ip, args.port)
The first robot will send an instruction to the second robot as soon as it reaches the end point. It's still easy to run a relay. Focus on running!