The Noah unmanned ship of Amu Lab has been on the market for some time. After many investigations on the developers, we found that many developers are interested in the communication implementation of the Noah unmanned ship. In order to help everyone better In this issue, we will share some experience with you about the linux programming technology and ROS system used in Noah's unmanned ship.
Open source autonomous unmanned ship based on Ardupilot
https://www.bilibili.com/video/BV1AR4y167ne/?vd_source=83d699d29d0a56e0274cd41e59a6c3a9
The unmanned ship developed based on the Ardupilot platform - "Noah (2022 model)", not only has a fast driving speed and a long battery life, but also has functions such as 4G remote control, waypoint planning, video return, etc., which can be applied to various developments Scenes. Amu Lab, official account: Amu Lab's new products are on the shelves | 2022 "Noah" unmanned ship is officially on sale!
When it comes to unmanned ships, we have to talk about ROS first. What is ROS?
ROS is the abbreviation of Robot Operating System (Robot Operating System). In fact, it is not our traditional operating system. It is called an operating system because the distributed software framework and message communication mechanism it provides allow us to coordinate And control the various components of the robot, just like the operating system manages various parts of the computer, making robot development simple and efficient.
Let's take the simulation of running a little turtle as an example to help you better understand the communication between ROS:
First, we open three terminals, enter roscore to open the rosmaster node, enter rosrun turtlesim turtlesim_nod to run the little turtle simulation node, and enter px -ef to view all the processes of the system:
Here, pay attention to the circled process in the above figure. The first two processes are generated by entering the roscore command, because you can see that the parent process of the two is 4069, and the 4069 process is mounted in pts/0, and the command / usr/bin/python3/opt/ros/noetic/bin/roscore. This command is the command that actually runs in Linux after being interpreted by the ROS command line script after entering roscore. If you try it, you will find that you can also run roscore by directly entering the above command in the terminal. So we can guess what happened when we started roscore?
When starting roscore, ROS generates two processes, the first is the master process, followed by the parameter --core -p 11311 where 11311 is the default TCP port number in the ROS system (since the TCP network communication is used as the process Inter-communication is prohibited, then this means that ROSMaster only needs to be on the same local area network as the node, and does not need to be on the same host, which is also the key to ROS multi-machine communication), which is used for communication and information exchange between ROS nodes. When a ROS node wants to communicate with another node, it needs to first connect to the master node (ROS Master) and register its name, type, URI and other information with it. The transmission of these information is completed on port 11311 through the TCP/IP protocol.
The second process is rosout, which is used to receive and publish ROS log messages. In ROS, log messages are used to record the running status information, warnings and errors of the program. After the above steps are completed, the started little turtle simulation generates a process.
In general, ROS nodes are one process after another, and they exchange data through inter-process communication in linux, making inter-process communication easier.
In Noah's unmanned ship, we choose to use dronekit to communicate with ROS because dronekit is developed based on Python language, the syntax is relatively simple, and it is more friendly to APM flight control support, which is easy for developers to get started.
So the question is, how to let dronekit get the data of ROS nodes? In other words, what is the means of inter-process communication?
There are many ways to communicate between processes, such as shared memory, well-known pipes, etc. This time we use socket communication.
First, we implemented a ROS node in the onboard computer (Raspberry Pi) of the unmanned ship, obtained the desired data from the drone by subscribing to the topic, and then sent it to the user through socket communication. The control code written by dronekit. In the whole process, the ROS node on the unmanned ship acts as a transfer station. After receiving the topic of the drone, it forwards it to the unmanned ship with a socket, and forwards the socket information of the unmanned ship with a topic. to the drone.
In this communication process, the problem that ROS nodes may encounter is: the callback function of the ROS topic (that is, the last parameter of Subscribe) is a thread, and the trigger of this thread is determined by ROS, that is, ros::spinOnce() and ros::spin() determines that when the program runs to ros::spinOnce(), the callback function will be executed (if there is a message), while ros::spin() will always execute the callback function (if there is message), in order to solve this problem, it is necessary to use the non-blocking mode of the socket mode in the inter-process communication to keep the callback function being monitored all the time.
The pseudo code for the ROS node to receive ship information is shown below. Before the main loop, it is mainly the necessary initialization process for socket programming, and then wait for it to receive information. If no information is received, ROS must check the callback function once.
int sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //创建套接字sockfd,指定协议为UDP
struct sockaddr_in server_addr;//创建用来绑定自身信息的结构体server_addr
memset(&server_addr, 0, sizeof(server_addr));//将server_addr数据全部置0
server_addr.sin_family = AF_INET;//设置协议族
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");//设置本地IP
server_addr.sin_port = htons(8080);//设置本地端口
bind(sockfd, (const struct sockaddr *)&server_addr, sizeof(server_addr))//将IP和端口绑定
char buffer[BUFFER_SIZE];
struct sockaddr_in client_addr;//得到的有关于发送端的数据都会保存在clint_addr里面
socklen_t addr_len = sizeof(client_addr);
while(ros::ok){
int recv_bytes = recvfrom(sock, buffer, sizeof(buffer),
MSG_DONTWAIT,
(struct sockaddr*)&addr, &client_address_len);
//第四个参数为设置成非阻塞,recv_bytes为接收到的数据大小
if(recv_bytes > 0){
//说明接收到船的数据,就可以进行处理后,用ROS的topic发送出去
}
ros::spinOnce();
rate.sleep();
}
It is easier and more convenient for Dronekit to implement socket inter-process communication. The code comments are very clear. The examples are as follows:
localaddr = ("127.0.0.1",12345)
server_address = "127.0.0.1"
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)#套接字初始化
udp_socket.setblocking(False)#设置为非阻塞
udp_socket.bind(localaddr)
sendbuf = '(' + str(vehicle.location.local_frame.east) + ','
+ str(vehicle.location.local_frame.east)+')'
while True:
#recvfrom如果没有接收到信息会抛出异常,
try:
data, address = udp_socket.recvfrom(1024)
print("got server data: ", data, "IP address", address)
except socket.error as e: #捕获这个异常,就可以知道没收到信息
udp_socket.sendto(sendbuf, server_address)#将信息发给ROS节点
It can be seen that the socket communication method is simple to operate and low in difficulty, and can easily realize the communication between ROS+dronekit. In addition, the socket communication method can also realize network communication, support communication between different hosts, and have rich application scenarios. Subsequent developers can also write a host computer interface in QT through this communication method, issue instructions to the dronekit control part through sockets, and even use matlab to issue instructions to control the direction of the ship, which is highly operable.
Due to the limited space and content, today’s sharing is here first. Before learning the communication between ROS+dronekit, it is recommended that you understand the basic knowledge of threads, processes, network programming and Linux in advance to avoid subsequent learning. . In addition, if you are interested in our Noah unmanned ship or have other questions during use, please leave us a message to discuss related technologies~