0

I’m trying to print data for 0 to 1080 steps in real time using socket. Unfortunately, I can’t use ROS2 because it’s too much of a headache to set up on Windows and Mac M2. I’m using Ethernet to communicate via a socket with the UAM-05LP. However, pyserial doesn’t seem to be working for me. Below is the code I have right now for the UAM-05LP. Comparing the data obtained from the official software to my implementation, there’s a significant difference: the official software shows consistent and real-time data, while the data from the socket connection is inconsistent and different.

Problem list here:

  1. The data obtained from the Hokuyo UAM-05LP using PySerial is different from the data displayed by the Hokuyo official software. See the below photo showing the terminal output and the official Hokuyo software for comparison.

  2. I want to use a NumPy array instead of a regular list for better performance. I’m looking for suggestions on how to achieve this.

Question I have: What did I do wrong? lol

A screenshot of an official software log(urgbenriplus on windows): (The log shows the step and range data arranged in table format below)

Step Range 0
0 928
1 1155
2 1155
3 1124
4 906
5 827
____________
0 961
1 1158
2 1165
3 1145
4 908
5 839
____________
0 925
1 1154
2 1157
3 1138
4 912
5 837
____________
0 939
1 1160
2 1161
3 1148
4 893
5 841

my terminal output:

lidar data to 5 indexes: [2702, 2255, 2174, 2158, 2149]
lidar data to 5 indexes: [41, 41, 46, 46, 46]
lidar data to 5 indexes: [2304, 2240, 2240, 2240, 2240]
lidar data to 5 indexes: [1553, 1553, 1549, 1555, 1544]
lidar data to 5 indexes: [48, 48, 48, 48, 49]
lidar data to 5 indexes: [2752, 3008, 3456, 3968, 0]
lidar data to 5 indexes: [3320, 3310, 3307, 3295, 3291]
lidar data to 5 indexes: [8, 8, 8, 8, 9]
lidar data to 5 indexes: [1408, 832, 768, 1024, 1024]
lidar data to 5 indexes: [2473, 1971, 1777, 1735, 1729]
lidar data to 5 indexes: [36, 35, 35, 35, 35]
lidar data to 5 indexes: [128, 2496, 704, 3648, 3648]
lidar data to 5 indexes: [666, 648, 648, 659, 653]
lidar data to 5 indexes: [36, 37, 37, 37, 36]
lidar data to 5 indexes: [1152, 2112, 2176, 1728, 64]
lidar data to 5 indexes: [3228, 3210, 3222, 3273, 3262]
lidar data to 5 indexes: [0, 64, 0, 64, 1957]
lidar data to 5 indexes: [1541, 1538, 1527, 1485, 1187]
lidar data to 5 indexes: [48, 48, 48, 48, 49]
lidar data to 5 indexes: [2880, 3200, 3136, 3584, 3968]
lidar data to 5 indexes: [3316, 3316, 3306, 3297, 3293]
lidar data to 5 indexes: [8, 8, 8, 8, 8]

So, see the big difference between terminal and table from the official program. What should I do to make it more accurate and same as first sample?

See the code below:

import socket
import traceback
import time
class HokuyoLiDAR:
 def __init__(self, ip_address="192.168.0.10", port=10940):
 self.socket = None
 self.ip_address = ip_address
 self.port = port
 self.is_connected = False
 def connect(self):
 try:
 if self.is_connected:
 return True
 self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 self.socket.settimeout(5)
 print(f"Attempting to connect to {self.ip_address}:{self.port}")
 self.socket.connect((self.ip_address, self.port))
 print("Connected to LiDAR")
 # Initialize SCIP2.0 protocol
 self.socket.sendall(b"SCIP2.0\n")
 response = self.socket.recv(1024).decode('ascii')
 if "SCIP2.0" not in response:
 raise ConnectionError("Failed to initialize SCIP2.0 protocol")
 self.socket.sendall(b"VV\n")
 response = self.socket.recv(1024).decode('ascii')
 if not response:
 raise ConnectionError("No response from status request")
 self.is_connected = True
 print("Successfully initialized SCIP2.0 protocol")
 return True
 except Exception as e:
 print(f"Connection failed: {e}")
 if self.socket:
 self.socket.close()
 self.socket = None
 self.is_connected = False
 return False
 def decode_data(self, data: str) -> dict:
 """Decode the SCIP2.0 data format into human-readable format"""
 try:
 lines = data.strip().split('\n')
 if len(lines) < 3:
 return {"error": "Incomplete data"}
 # Parse measurement data
 distances_mm = []
 # Process each data line
 for line in lines[2:]: # skip steps and timestamp
 if not line.strip():
 continue
 # Skip line identifier (first 2 chars)
 data_line = line[2:] if len(line) > 2 else line
 # Process 3-character blocks
 for i in range(0, len(data_line), 3):
 if i + 2 < len(data_line):
 # Decode the 3-character block
 chars = data_line[i:i + 3]
 # Convert to distance in millimeters
 value = ((ord(chars[1]) - 0x30) << 6) | (ord(chars[2]) - 0x30)
 distances_mm.append(value)
 return distances_mm
 except Exception as e:
 return {"error": f"Decoding error: {str(e)}"}
 def start_continuous_measurement(self):
 try:
 if not self.is_connected:
 raise ConnectionError("Not connected to LiDAR")
 # Stop any existing measurement
 self.socket.sendall(b"QT\n")
 response = self.socket.recv(1024).decode('ascii')
 # Start new measurement
 command = "MD0000108000100\n"
 self.socket.sendall(command.encode())
 response = self.socket.recv(1024).decode('ascii')
 if not response.startswith("MD"):
 raise ConnectionError("Failed to start measurement")
 return response
 except Exception as e:
 print(f"Error starting measurement: {e}")
 self.is_connected = False
 raise
 def read_measurement(self):
 try:
 if not self.is_connected:
 if not self.connect():
 return None
 data = self.socket.recv(4096).decode('ascii')
 if not data:
 return None
 decoded = self.decode_data(data)
 print("lidar data to 5 indexes: ", decoded[:5])
 return decoded[:1080] # Hokuyo ignores anything after 1080 so following the same example
 except socket.timeout:
 print("Timeout while reading data")
 return None
 except Exception as e:
 print(f"Error reading measurement: {e}")
 traceback.print_exc()
 self.is_connected = False
 return None
 def disconnect(self):
 if self.socket:
 try:
 self.socket.close()
 except:
 pass
 self.socket = None
 self.is_connected = False
 print("Disconnected from LiDAR")
lidar = HokuyoLiDAR()
if lidar.connect():
 lidar.start_continuous_measurement()
 try:
 while True:
 scan = lidar.read_measurement()
 time.sleep(0.1)
 except KeyboardInterrupt:
 lidar.disconnect()

I’m expecting to print accurate data, just like the official software program displays

asked Jan 22, 2025 at 2:13

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.