智能小车(八)ros实现将智能小车数据通过TCP/IP发送到上位机网关

ros实现将智能小车数据通过TCP/IP发送到上位机网关
这里主要注意:
将浮点型数据*1000转换成int型数据然后分字节储存(另取一个字节作为符号位)。没有用struct.pack进行字节流打包,原因是不同平台,字节流的打包浮点型数据不一样,又要加上包头等校验信息,所以这里分别用单字节保存在列表中,然后sock.sendall(struct.pack(“B”*len(list_send),list_send))
学到的点
1、
在 Python 中,
是一个解包运算符(unpacking operator)。它可以应用于可迭代对象,如列表、元组等,并将可迭代对象中的元素解包为单独的参数。

在给定的代码中,*list_send 使用解包运算符 * 将列表 list_send 中的元素作为单独的参数传递给 struct.pack 函数。这意味着 struct.pack 函数将接收列表中的每个元素作为单独的参数。如果列表 list_send 包含三个元素 [1, 2, 3],那么 *list_send 将被解包为 1, 2, 3。

这种解包操作是为了确保 struct.pack 函数能够接收正确数量的参数,并将它们打包为字节流发送到 socket 连接。
B是无符号8位
len(list_send)是链表长度(列表中元素个数)
2、
这里sock.connect((TCP_IP, TCP_PORT))会报错异常终止程序运行我们用try except就非常好

while not connect:try:sock.connect((TCP_IP, TCP_PORT))print("TCP/IP连接成功")except:time_connect+=1print("TCP/IP连接失败次数:%d" % time_connect)time.sleep(10)

3、def send_data(car_subscriber): 写子函数时这个形参随便写调用传入的是什么就是什么类型
4、转16位高低8位分别存储

    int16_num=int(abs(raw_data.twist.linear.y)*1000)&0xFFFFlist_raw[4]=int16_num&0xFF list_raw[5]=(int16_num>>8)&0xFF 

5、创建套接字 固定IP和端口否则端口会自动分配

local_ip='192.168.0.11'
local_port=8090
TCP_IP = '192.168.1.81'
TCP_PORT = 8090# 创建TCP/IP客户端套接字 AF_INET是指 IPv4 地址族 参数是套接字(socket)类型,用于指定 socket 的传输协议是基于流(stream)的,也就是 TCP/IP
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((local_ip,local_port))
# 获取实际分配的IP地址和端口号
actual_ip, actual_port = sock.getsockname()
# 打印实际分配的IP地址和端口号
print("Successfully bound to {}:{}".format(actual_ip, actual_port))
#!/usr/bin/env python
# encoding: utf-8
import binascii
from sqlite3 import connect
from threading import local
import time
import rospy
from std_msgs.msg import Float32
from sensor_msgs.msg import Imu, BatteryState
import struct
import socket
from geometry_msgs.msg import Twist
from time import sleep
#当前车头方向
x_yaw=0
# 设置TCP/IP服务器地址和端口号
local_ip='192.168.0.11'
local_port=8090
TCP_IP = '192.168.1.81'
TCP_PORT = 8090
""" TCP_IP = '192.168.0.2'
TCP_PORT = 8888  """
# 创建TCP/IP客户端套接字 AF_INET是指 IPv4 地址族 参数是套接字(socket)类型,用于指定 socket 的传输协议是基于流(stream)的,也就是 TCP/IP
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((local_ip,local_port))
# 获取实际分配的IP地址和端口号
actual_ip, actual_port = sock.getsockname()
# 打印实际分配的IP地址和端口号
print("Successfully bound to {}:{}".format(actual_ip, actual_port))
connect = False
time_connect=0
while not connect:try:sock.connect((TCP_IP, TCP_PORT))print("TCP/IP连接成功")connect=Trueexcept:time_connect+=1print("TCP/IP连接失败次数:%d" % time_connect)time.sleep(10)# 订阅小车速度、IMU角速度、电压和电量
class RosTcpIPPublisher:def __init__(self):self.twist =Twist()self.twist.linear.x=0.0self.twist.linear.y=0.0self.twist.linear.z=0.0self.twist.angular.x = 0.0self.twist.angular.y = 0.0self.twist.angular.z =0.0self.battery = 0.0rospy.Subscriber('/vel_raw', Twist, self.vel_callback)rospy.Subscriber('voltage', Float32, self.battery_callback)def vel_callback(self, msg):self.twist.linear.x = msg.linear.xself.twist.linear.y = msg.linear.yself.twist.linear.z = msg.linear.zself.twist.angular.x = msg.angular.xself.twist.angular.y = msg.angular.yself.twist.angular.z = msg.angular.zdef battery_callback(self, msg):self.battery = msg.data# 打包数据并发送到TCP/IP服务器
def send_data(car_subscriber):while not rospy.is_shutdown():list_data=trans_data(car_subscriber)list_send=clc_data(list_data)# 发送数据到TCP/IP服务器sock.sendall(struct.pack("B"*len(list_send),*list_send))sleep(1)
def trans_data(raw_data):list_raw=[0]*19if raw_data.twist.linear.x>0:list_raw[0]=1else:list_raw[0]=0if raw_data.twist.linear.y>0:list_raw[3]=1else:list_raw[3]=0if raw_data.twist.linear.z>0:list_raw[6]=1else:list_raw[6]=0if raw_data.twist.angular.x>0:list_raw[9]=1else:list_raw[9]=0if raw_data.twist.angular.y>0:list_raw[12]=1else:list_raw[12]=0if raw_data.twist.angular.z>0:list_raw[15]=1else:list_raw[15]=0int16_num=int(abs(raw_data.twist.linear.x)*1000)&0xFFFFlist_raw[1]=int16_num&0xFF list_raw[2]=(int16_num>>8)&0xFF int16_num=int(abs(raw_data.twist.linear.y)*1000)&0xFFFFlist_raw[4]=int16_num&0xFF list_raw[5]=(int16_num>>8)&0xFF int16_num=int(abs(raw_data.twist.linear.z)*1000)&0xFFFFlist_raw[7]=int16_num&0xFF list_raw[8]=(int16_num>>8)&0xFF int16_num=int(abs(raw_data.twist.angular.x)*1000)&0xFFFFlist_raw[10]=int16_num&0xFF list_raw[11]=(int16_num>>8)&0xFF int16_num=int(abs(raw_data.twist.angular.y)*1000)&0xFFFFlist_raw[13]=int16_num&0xFF list_raw[14]=(int16_num>>8)&0xFF int16_num=int(abs(raw_data.twist.angular.z)*1000)&0xFFFFlist_raw[16]=int16_num&0xFF list_raw[17]=(int16_num>>8)&0xFF list_raw[18]=int(raw_data.battery*10)&0xFFreturn list_raw
def clc_data(list_data):count=0     #i=0total_sum=0current=list_datalist_send=[0]*0x26list_send[0]=0xCClist_send[1]=0xEE#总长list_send[2]=0x26list_send[3]=0x00#8Bytefor i in range(8):list_send[i+4]=0x00#节点类型list_send[12]=0x88list_send[13]=0x13#指令list_send[14]=0x01#功能字#车辆编号list_send[15]=0x01count=len(list_data) for i in range(count):list_send[i+16]=list_data[i]#数据长度len_L=20len_H=00list_send[35]=len_Llist_send[36]=len_Hfor i in range(37):total_sum+=list_send[i]total_sum=total_sum%256list_send[37]=total_sumreturn list_send
if __name__ == '__main__':rospy.init_node('ros_tcpip_publish',anonymous=False)try:car_subscriber = RosTcpIPPublisher()sleep(2)send_data(car_subscriber)rospy.spin()sock.close()except Exception as e:rospy.loginfo("ROS_TCP/IP_ERROR!!!")print("发生异常",str(e))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/633985.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣(leetcode)第830题较大分组的位置(Python)

830.较大分组的位置 题目链接:830.较大分组的位置 在一个由小写字母构成的字符串 s 中,包含由一些连续的相同字符所构成的分组。 例如,在字符串 s “abbxxxxzyy” 中,就含有 “a”, “bb”, “xxxx”, “z” 和 “yy” 这样的…

C++ //练习 2.11 指出下面的语句是声明还是定义:

C Primer(第5版) 练习 2.11 练习 2.11 指出下面的语句是声明还是定义: ( a ) extern int ix 1024; ( b ) int iy; ( c ) extern int iz; 环境:Linux Ubuntu(云服务器) 工具:vim 解释 ( …

time-to-event数据的参考资料

目录 一、书籍推荐 二、方法论文章 Introductory/Overview Articles Censoring Non-parametric survival methods Semi-parametric survival methods Parametric survival methods Time-Varying Covariates Competing risk analysis Analysis of clustered data and fra…

基于Java+SSM框架的智慧医疗问诊管理系统【附源码】

基于JavaSSM框架的智慧医疗问诊管理系统详细设计和实现【附源码】 🍅 作者主页 央顺技术团队 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 文末获取源码联系方式 📝 🍅 查看下方微信号获取联系方式 承接各…

高效视频剪辑:视频合并让视频焕然一新,添加背景音乐更动听

随着社交媒体和数字内容的普及,视频剪辑已成为一项常用的技能。除了基本的剪辑技巧外,添加合适的背景音乐也是提升视频质量的方法。下面来看云炫AI智剪的高效视频剪辑技巧——如何批量合并视频,添加动听的背景音乐。 视频合并后的效果展示&a…

Interface 接口

/* * 语法1:使用interface关键字定义 * 语法2:接口中,允许定义“抽象方法”,public 和 abstract关键字可以省略 * 语法3:接口中,允许定义“默认方法” * 语法4:实现类通过implements关键字实现接…

What is `@Repository` does?

Repository 是Spring注解,标识数据访问层组件(DAO, Data Access Object) 当一个类被标记为 Repository 时: 1、组件扫描与自动代理: Spring通过组件扫描(Component Scan)机制发现带有 Reposit…

编程语言的比较—c语言,c++与java,c#的比较

c语言是历史悠久的语言,不仅可以开发应用程序,还可以用来编写操作系统。如果对接近硬件的部分进行操作,c语言是不二之选。 c语言是c语言中增加面向对象功能的编程语言。通常情况下,c可以编译c语言编写的代码。c广泛应用于微型计算…

【AI绘画+本地部署】基于krita的AI绘画(含windows一键整合包)

comfyuikrita所有相关资源整合包(无需下载后面链接)百度网盘:https://pan.baidu.com/s/1iwNRpdTaD26YbzSDm6WLDA?pwdbur8 –来自百度网盘超级会员V4的分享 krita绘画软件官网地址 https://krita.org/en/download/krita-desktop/ krita-ai-diffusion 插件&#xff…

数据库:园林题库软件(《城市绿地系统规划》答题卷四)

《城市绿地系统规划》答题卷四 填空题 1、生产绿地是指为城市绿化提供苗木、花草、种子的苗圃、草圃等圃地,是为城市绿化服务的生产、科研实验绿地。 园林苗圃的规模按照其用地面积来划分,可分为大型苗圃、中型苗圃、小型苗圃三类。 2、防护绿地是出…

P1451 求细胞数量——深搜、广搜

求细胞数量 题目描述 一矩形阵列由数字 0 0 0 到 9 9 9 组成,数字 1 1 1 到 9 9 9 代表细胞,细胞的定义为沿细胞数字上下左右若还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。 输入格式 第一行两个整数代表矩阵大小 n n n 和…

计算机网络-ACL访问控制列表

上一篇介绍NAT时候就看到了ACL这个东西了,这个是什么意思?有什么作用呢? 一、ACL访问控制列表 访问控制列表 (ACL, Access Control List)是由一系列permit或deny语句组成的、有序规则的列表。ACL是一个匹配工具,能够对报文进行匹配…

鸿蒙原生应用/元服务实战-AGC团队账户

多人及内外结合去开发运营鸿蒙原生应用元服务时,需要用到团队账户,AGC提供了强大的团队角色与权限分工能力。 团队帐号是开发者联盟为实名开发者提供的多个成员帐号登录与权限管理服务。当前团队帐号支持成员参与应用市场(付费推广、应用内付…

设备树(1)-设备树是什么?设备树基础概念及语法

1.简介 设备树:device tree DTS:设备树源码文件,采用树形结构描述板级信息,例如IIC、SPI等接口接了哪些设备 DTSI:设备树头文件,描述SOC级信息,例如几个CPU、主频多少、各个外设控制信息等 DTB…

vue列表飞入效果

效果 实现代码 <template><div><button click"add">添加</button><TransitionGroup name"list" tag"ul"><div class"list-item" v-for"item in items" :key"item.id">{{ i…

校园水电抄表系统

校园水电抄表系统是一种现代化的水电管理方式&#xff0c;它通过高科技手段实现对校园内水电使用情况的实时监测和数据化管理&#xff0c;从而提高水电资源的利用效率&#xff0c;降低管理成本&#xff0c;为构建绿色、环保、节约型校园奠定基础。 一、系统概述 校园水电抄表…

K8S---NetworkPolicy

一、简介 在操作系统中,服务器有出口流量和入口流量,可以为服务器设置网络策略,允许哪些ip可以访问本机器的哪些端口,设置本机器可以访问哪些其他机器;在K8S系统类似,pod如同服务器,可以设置哪些其他pod可以访问本pod的哪些端口,也可以设置本pod可以访问外部哪些pod的…

力扣 | 11. 盛最多水的容器

双指针解法–对撞指针 暴力解法public int maxArea1(int[] height) {int n height.length;int ans 0;for (int i 0; i < n; i) {for (int j i 1; j < n; j) {int area Math.min(height[i], height[j]) * (j - i);ans Math.max(ans, area);}}return ans;}双指针解法…

vue动画(transition)

Vue动画&#xff08;transition&#xff09; 动画列表&#xff08;选择其中一个即可&#xff09; /* fade */ .fade-enter-active, .fade-leave-active {transition: opacity 0.28s; } ​ .fade-enter, .fade-leave-active {opacity: 0; } /* fade */ ​ /* fade-transform */…

ARP相关

ARP报文格式&#xff1a; 目的以太网地址&#xff0c;48bit&#xff0c;发送ARP请求时&#xff0c;目的以太网地址为广播MAC地址&#xff0c;即0xFF.FF.FF.FF.FF.FF。 源以太网地址&#xff0c;48bit。 帧类型&#xff0c;对于ARP请求或者应答&#xff0c;该字段的值都为0x08…