Question:
The main content of this post is that the robotic arm starts RVIZ in the ROS environment, which will cause the system to freeze, affecting the program’s crash. Is there any way to improve the stability of RVIZ and enable it to operate normally?
Operation:
I run the program with two versions of myCobot 280 series robotic arm. One is the robotic arm with m5stack master control, and another one is the robotic arm with Raspberry Pi 4B master control.
The M5Stack’s robotic arm runs in a laptop configuration, and the Raspberry Pi’s robotic arm runs in its own Raspberry Pi 4B (64-bit 1.5GHz quad-core).
Figure is myCobot280M5Stack
Figure is myCobot280-Pi
Here are a few ways to use myCobot280 with RVIZ.
Slider Control:
Move the slider to control the movement of the myCobot280, and the movement of the myCobot280 will be fed into the RVIZ interface in real-time.
Movement Planning:
Given two positions, one is position A, and the other is position B, send commands to the myCobot280 to move from A to B.
Artificial Intelligence Kit:
Guide the robot through robot vision and realize intelligent grasping simultaneously. The intellectual grasping of wood blocks and the intelligent grasping of image objects have been developed.
Problems
1: After the myCobot280 runs normally for a period of time, the machine heats up and the RVIZ cannot run normally.
2: On the Raspberry Pi version, after turning on the RVIZ, it was found that the computer’s CPU was instantly occupied and could not run stably.
Try to solve
-
At first, I thought that the file (URDF) of the built model was too large, which made RVIZ freeze. We optimized the model file (URDF) and found the effect insignificant.
Reflections:
1: It is relatively stable to run programs with a small amount of code, so is it possible to optimize the code to improve the stability of RVIZ? We are currently trying to migrate its adaptation environment from ROS1 to ROS2 to see if the whole will be more stable.
2: When the RVIZ is turned on, the CPU is full. We try to start with the CPU to see if we can improve the performance of the CPU processing to be more stable. -
After I modified the CPU processing capability of the virtual machine, it was much more stable when I used it again. You may think that Raspberry Pi is a computer. How to upgrade the CPU? Is it going to have to change the motherboard? We use a socket method to connect to the Raspberry Pi (like a TCP/IP connection) to solve this problem.
Socket function:
The principle of the socket method is to use its virtual machine to establish a connection with myCobot280-Pi (remote control)undefined and the virtual machine sends instructions to myCobot280-Pi instead of sending instructions to the robotic arm in its Pi motherboard. This solves the problem of low CPU performance.
code:
logger = logging.getLogger(name)
logger.setLevel(logging.DEBUG)
LOG_FORMAT = "%(asctime)s - %(levelname)s - %(message)s"
#DATE_FORMAT = "%m/%d/%Y %H:%M:%S %p"
formatter = logging.Formatter(LOG_FORMAT)
# console = logging.StreamHandler()
# console.setFormatter(formatter)
save = logging.handlers.RotatingFileHandler(
"/home/ubuntu/mycobot_server.log", maxBytes=10485760, backupCount=1)
save.setFormatter(formatter)
logger.addHandler(save)
# logger.addHandler(console)
return logger
class MycobotServer(object):
def __init__(self, host, port):
try:
GPIO.setwarnings(False)
except:
pass
self.logger = get_logger("AS")
self.mc = None
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.s.bind((host, port))
print "Binding succeeded!"
self.s.listen(1)
self.connect()
def connect(self):
while True:
try:
print "waiting connect!------------------"
conn, addr = self.s.accept()
port_baud = []
while True:
try:
print "waiting data--------"
data = conn.recv(1024)
command = data.decode('utf-8')
if data.decode('utf-8') == "":
print("close disconnect!")
break
res = b'1'
command = command.replace(" ", "")
if len(port_baud) < 3:
port_baud.append(command)
if len(port_baud) == 3:
self.mc = serial.Serial(
port_baud[0], port_baud[1], timeout=float(port_baud[1]))
port_baud.append(1)
else:
self.logger.info(command)
command = self.re_data_2(command)
if command[3] == 170:
if command[4] == 0:
GPIO.setmode(GPIO.BCM)
else:
GPIO.setmode(GPIO.BOARD)
elif command[3] == 171:
if command[5]:
GPIO.setup(command[4], GPIO.OUT)
else:
GPIO.setup(command[4], GPIO.IN)
elif command[3] == 172:
GPIO.output(command[4], command[5])
elif command[3] == 173:
res = bytes(GPIO.input(command[4]))
self.write(command)
res = self.read()
if res == None:
res = b'1'
conn.sendall(res)
except Exception as e:
self.logger.error(str(e))
conn.sendall(str.encode("ERROR:"+str(e)))
break
except Exception as e:
self.logger.error(str(e))
conn.close()
def write(self, command):
self.mc.write(command)
self.mc.flush()
time.sleep(0.05)
def read(self):
data = None
if self.mc.inWaiting() > 0:
data = self.mc.read(self.mc.inWaiting())
return data
def re_data_2(self, command):
r2 = re.compile(r'[[](.*?)[]]')
data_str = re.findall(r2, command)[0]
data_list = data_str.split(",")
data_list = [int(i) for i in data_list]
return data_list
(The essence of the socket approach is to use a virtual machine to connect to the Raspberry Pi, and we then boost the CPU processing power of the virtual machine.)
Discuss:
For now, our solution for RVIZ is just this. I am wondering whether there is a better way to handle your RVIZ related issues. Everyone is welcome to discuss, and I will learn from your opinions and put them into practice.