Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
p x
earlywarning
Commits
dcb9ce75
Commit
dcb9ce75
authored
Jun 09, 2025
by
p x
Browse files
first
parent
009a6d77
Pipeline
#3092
canceled with stages
Changes
102
Pipelines
2
Show whitespace changes
Inline
Side-by-side
src/main/java/com/cusc/adas/v2x/dto/TracePointDto.java
0 → 100644
View file @
dcb9ce75
package
com.cusc.adas.v2x.dto
;
import
com.cusc.adas.v2x.utils.Order
;
//轨迹点
public
class
TracePointDto
{
//期望经度
@Order
(
1
)
private
double
expLongitude
;
//期望纬度
@Order
(
2
)
private
double
expLatitude
;
//期望速度
@Order
(
3
)
private
float
expSpeed
;
//期望加速度
@Order
(
4
)
private
float
expAcceleration
;
//期望航向角
@Order
(
5
)
private
double
expHeading
;
}
src/main/java/com/cusc/adas/v2x/dto/VehicleBodyDto.java
0 → 100644
View file @
dcb9ce75
package
com.cusc.adas.v2x.dto
;
public
class
VehicleBodyDto
{
private
VehicleInfoDto
vehicleInfo
;
}
src/main/java/com/cusc/adas/v2x/dto/VehicleInfoDto.java
0 → 100644
View file @
dcb9ce75
package
com.cusc.adas.v2x.dto
;
import
java.util.List
;
import
com.cusc.adas.v2x.utils.FieldDef
;
import
com.cusc.adas.v2x.utils.NumFlag
;
import
com.cusc.adas.v2x.utils.Order
;
import
com.cusc.adas.v2x.utils.RefNumFlag
;
/**
* 车辆基础信息
* @author huangml
*
*/
public
class
VehicleInfoDto
{
//车辆编号
@Order
(
1
)
@FieldDef
(
type
=
"BYTE"
,
isArray
=
true
,
length
=
8
)
private
String
vehicleId
;
//消息编号
@Order
(
2
)
@FieldDef
(
type
=
"BYTE"
,
isArray
=
true
,
length
=
8
)
private
long
messageId
;
//GNSS 时间戳
@Order
(
3
)
@FieldDef
(
type
=
"TIMESTAMP"
,
isArray
=
false
,
length
=
8
)
private
long
timestampGNSS
;
//GNSS 速度
@Order
(
4
)
private
float
velocityGNSS
;
//位置
@Order
(
5
)
private
PositionDto
position
;
//航向角
@Order
(
6
)
private
double
heading
;
//档位
@Order
(
7
)
private
short
tapPos
;
//方向盘转角
@Order
(
8
)
private
double
steeringAngle
;
//当前车速
@Order
(
9
)
private
float
velocity
;
//纵向加速度
@Order
(
10
)
private
float
accelerationLon
;
//横向加速度
@Order
(
11
)
private
float
accelerationLat
;
//垂向加速度
@Order
(
12
)
private
float
accelerationVer
;
//横摆角速度
@Order
(
13
)
private
float
yawRate
;
//油门开度
@Order
(
14
)
private
float
accelPos
;
//发动机输出转速
@Order
(
15
)
private
float
engineSpeed
;
//发动机扭矩
@Order
(
16
)
private
double
engineTorque
;
//制动踏板开关
@Order
(
17
)
private
short
brakeFlag
;
//制动踏板开度
@Order
(
18
)
private
float
brakePos
;
//制动主缸压力
@Order
(
19
)
private
int
brakePressure
;
//油耗
@Order
(
20
)
private
float
fuelConsumption
;
//车辆驾驶模式
@Order
(
21
)
private
short
driveMode
;
//目的地位置
@Order
(
22
)
private
Position2DDto
destLocation
;
//途经点数量
@Order
(
23
)
@NumFlag
private
short
passPointsNum
;
//途经点
@Order
(
24
)
@RefNumFlag
(
value
=
"passPointsNum"
)
private
List
<
Position2DDto
>
passPoints
;
}
src/main/java/com/cusc/adas/v2x/server/NettyUdpServer.java
0 → 100644
View file @
dcb9ce75
package
com.cusc.adas.v2x.server
;
import
io.netty.bootstrap.ServerBootstrap
;
import
io.netty.channel.ChannelFuture
;
import
io.netty.channel.ChannelInitializer
;
import
io.netty.channel.ChannelOption
;
import
io.netty.channel.EventLoopGroup
;
import
io.netty.channel.nio.NioEventLoopGroup
;
import
io.netty.channel.socket.SocketChannel
;
import
io.netty.channel.socket.nio.NioServerSocketChannel
;
import
io.netty.handler.logging.LogLevel
;
import
io.netty.handler.logging.LoggingHandler
;
public
class
NettyUdpServer
{
private
final
int
port
;
public
NettyUdpServer
(
int
port
)
{
this
.
port
=
port
;
// server port
}
public
void
start
()
throws
Exception
{
EventLoopGroup
bossGroup
=
new
NioEventLoopGroup
();
EventLoopGroup
workerGroup
=
new
NioEventLoopGroup
();
try
{
ServerBootstrap
b
=
new
ServerBootstrap
();
b
.
group
(
bossGroup
,
workerGroup
)
.
channel
(
NioServerSocketChannel
.
class
)
.
option
(
ChannelOption
.
SO_BACKLOG
,
128
)
.
handler
(
new
LoggingHandler
(
LogLevel
.
INFO
))
.
childHandler
(
new
ChannelInitializer
<
SocketChannel
>()
{
@Override
public
void
initChannel
(
SocketChannel
ch
)
throws
Exception
{
ch
.
pipeline
().
addLast
(
new
NettyUdpServerHandler
());
// channel to handler
}
});
ChannelFuture
f
=
b
.
bind
(
port
).
sync
();
System
.
out
.
println
(
"Server started on port "
+
port
);
f
.
channel
().
closeFuture
().
sync
();
}
finally
{
workerGroup
.
shutdownGracefully
();
bossGroup
.
shutdownGracefully
();
}
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
int
port
=
8082
;
NettyUdpServer
server
=
new
NettyUdpServer
(
port
);
server
.
start
();
}
}
src/main/java/com/cusc/adas/v2x/server/NettyUdpServerHandler.java
0 → 100644
View file @
dcb9ce75
package
com.cusc.adas.v2x.server
;
import
io.netty.buffer.ByteBuf
;
import
io.netty.buffer.Unpooled
;
import
io.netty.channel.Channel
;
import
io.netty.channel.ChannelHandlerContext
;
import
io.netty.channel.ChannelInboundHandlerAdapter
;
import
io.netty.util.CharsetUtil
;
public
class
NettyUdpServerHandler
extends
ChannelInboundHandlerAdapter
{
/**
* 读取数据实际(这里我们可以读取客户端发送的消息)
* @param ctx 上下文对象
* @param msg 客户端发送的数据
* @throws Exception
*/
@Override
public
void
channelRead
(
ChannelHandlerContext
ctx
,
Object
msg
)
throws
Exception
{
System
.
out
.
println
(
"server ctx ="
+
ctx
);
Channel
channel
=
ctx
.
channel
();
// 将 msg 转成一个 ByteBuf
// ByteBuf 是 Netty 提供的,不是 NIO 的 ByteBuffer.
ByteBuf
buf
=
(
ByteBuf
)
msg
;
System
.
out
.
println
(
"客户端发送的消息是: "
+
buf
.
toString
(
CharsetUtil
.
UTF_8
));
System
.
out
.
println
(
"客户端地址: "
+
channel
.
remoteAddress
());
}
/**
* 读取完毕,回复
* @param ctx
* @throws Exception
*/
@Override
public
void
channelReadComplete
(
ChannelHandlerContext
ctx
)
throws
Exception
{
// writeAndFlush 是 write + flush 将数据写入到缓存,并刷新
ctx
.
writeAndFlush
(
Unpooled
.
copiedBuffer
(
"Hello, Client!"
,
CharsetUtil
.
UTF_8
));
}
/**
* 处理异常, 一般是需要关闭通道
* @param ctx
* @param cause
* @throws Exception
*/
@Override
public
void
exceptionCaught
(
ChannelHandlerContext
ctx
,
Throwable
cause
)
throws
Exception
{
ctx
.
close
();
}
}
src/main/java/com/cusc/adas/v2x/server/UdpServer.java
0 → 100644
View file @
dcb9ce75
package
com.cusc.adas.v2x.server
;
import
java.net.InetSocketAddress
;
import
io.netty.bootstrap.Bootstrap
;
import
io.netty.channel.ChannelFuture
;
import
io.netty.channel.ChannelInitializer
;
import
io.netty.channel.ChannelOption
;
import
io.netty.channel.EventLoopGroup
;
import
io.netty.channel.nio.NioEventLoopGroup
;
import
io.netty.channel.socket.DatagramChannel
;
import
io.netty.channel.socket.nio.NioDatagramChannel
;
public
class
UdpServer
{
private
final
int
port
;
public
UdpServer
(
int
port
)
{
this
.
port
=
port
;
}
// public void start() throws Exception {
// EventLoopGroup group = new NioEventLoopGroup();
//
// try {
// Bootstrap b = new Bootstrap();
// b.group(group)
// .channel(NioDatagramChannel.class)
// .handler(new ChannelInitializer<DatagramChannel>() {
// @Override
// protected void initChannel(DatagramChannel ch) throws Exception {
// ch.pipeline().addLast(null);
// }
// });
//
// ChannelFuture f = b.bind(port).sync();
// System.out.println("Server started on port " + port);
// f.channel().closeFuture().sync();
// } finally {
// group.shutdownGracefully();
// }
// }
public
void
run
()
throws
Exception
{
EventLoopGroup
group
=
new
NioEventLoopGroup
();
try
{
Bootstrap
b
=
new
Bootstrap
();
b
.
group
(
group
)
.
channel
(
NioDatagramChannel
.
class
)
.
option
(
ChannelOption
.
SO_BROADCAST
,
true
)
.
localAddress
(
new
InetSocketAddress
(
port
))
.
handler
(
new
ChannelInitializer
<
DatagramChannel
>()
{
// @Override
// protected void initChannel(DatagramChannel ch) {
// ch.pipeline().addLast(new SimpleChannelInboundHandler<DatagramPacket>() {
// @Override
// protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) {
// byte[] data = new byte[msg.readableBytes()];
// msg.readBytes(data);
// String received = new String(data).trim();
// System.out.println("Server received: " + received);
// ByteBuf response = Unpooled.copiedBuffer("Echo: " + received, CharsetUtil.UTF_8);
// ctx.writeAndFlush(response); // Echo the received message back to the client
// }
// });
// }
@Override
protected
void
initChannel
(
DatagramChannel
ch
)
{
ch
.
pipeline
().
addLast
(
new
UdpServerHandler
());
}
});
ChannelFuture
f
=
b
.
bind
().
sync
();
// Bind and start to accept incoming connections.
System
.
out
.
println
(
"UDP server started on port "
+
port
);
f
.
channel
().
closeFuture
().
await
();
// Wait until the server socket is closed.
}
finally
{
group
.
shutdownGracefully
();
// Shut down all event loops to terminate all threads and release all resources.
}
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
new
UdpServer
(
8082
).
run
();
// Start the server on port 8080
}
}
src/main/java/com/cusc/adas/v2x/server/UdpServerHandler.java
0 → 100644
View file @
dcb9ce75
package
com.cusc.adas.v2x.server
;
import
com.cusc.adas.v2x.dto.VehicleBodyDto
;
import
com.cusc.adas.v2x.utils.Parse
;
import
com.cusc.adas.v2x.vo.VehicleMessage
;
import
io.netty.buffer.ByteBuf
;
import
io.netty.buffer.Unpooled
;
import
io.netty.channel.ChannelHandlerContext
;
import
io.netty.channel.SimpleChannelInboundHandler
;
import
io.netty.channel.socket.DatagramPacket
;
import
io.netty.util.CharsetUtil
;
public
class
UdpServerHandler
extends
SimpleChannelInboundHandler
<
DatagramPacket
>
{
//public static final Logger log = Logger.getLogger(UdpServerHandler.class);
@Override
public
void
channelActive
(
ChannelHandlerContext
ctx
)
throws
Exception
{
//log.info("UDP通道已经连接");
System
.
out
.
println
(
"UDP通道已经连接"
);
super
.
channelActive
(
ctx
);
}
@Override
protected
void
channelRead0
(
ChannelHandlerContext
ctx
,
DatagramPacket
packet
)
throws
Exception
{
// 处理接收到的数据包,例如打印消息内容或回复客户端等。
// ByteBuf buf = (ByteBuf) msg;
// String message = packet.content().toString();
// byte[] req = new byte[buf.readableBytes()];
ByteBuf
buf
=
(
ByteBuf
)
packet
.
copy
().
content
();
byte
[]
req
=
new
byte
[
buf
.
readableBytes
()];
buf
.
readBytes
(
req
);
String
body
=
new
String
(
req
,
CharsetUtil
.
UTF_8
);
String
hexString
=
Parse
.
byteToHexString
(
req
);
// byte[] bytes = HexStringToByteArray.hexStringToByteArray(body);
if
(
hexString
.
substring
(
10
,
12
).
equals
(
"15"
))
{
ByteBuf
byteBuf
=
Unpooled
.
wrappedBuffer
(
req
);
VehicleMessage
vehicleMessage
=
Parse
.
parse
(
byteBuf
,
new
VehicleMessage
());
System
.
out
.
println
(
"Received message: "
+
vehicleMessage
);
VehicleBodyDto
vehicleBodyDto
=
new
VehicleBodyDto
();
Parse
.
convoterBean
(
vehicleMessage
.
getVehicleMessageBody
(),
vehicleBodyDto
);
System
.
out
.
println
(
"Received message: "
+
vehicleBodyDto
);
}
// 回复客户端消息(可选)
// ctx.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer("Response", io.netty.util.CharsetUtil.UTF_8), packet.sender()));
}
}
src/main/java/com/cusc/adas/v2x/utils/FieldDef.java
0 → 100644
View file @
dcb9ce75
package
com.cusc.adas.v2x.utils
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
@Retention
(
RetentionPolicy
.
RUNTIME
)
// 注解在运行时可用
@Target
(
ElementType
.
FIELD
)
// 注解只能用于字段(属性)
public
@interface
FieldDef
{
int
length
()
default
1
;
String
type
();
boolean
isArray
()
default
false
;
boolean
isAutoLength
()
default
false
;
}
src/main/java/com/cusc/adas/v2x/utils/GenericTypeUtil.java
0 → 100644
View file @
dcb9ce75
package
com.cusc.adas.v2x.utils
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.ParameterizedType
;
import
java.lang.reflect.Type
;
public
class
GenericTypeUtil
{
public
static
Class
<?>
getListGenericType
(
Class
<?>
clazz
,
String
fieldName
)
throws
NoSuchFieldException
{
Field
field
=
clazz
.
getDeclaredField
(
fieldName
);
Type
genericType
=
field
.
getGenericType
();
if
(
genericType
instanceof
ParameterizedType
)
{
ParameterizedType
pt
=
(
ParameterizedType
)
genericType
;
Type
[]
actualTypes
=
pt
.
getActualTypeArguments
();
if
(
actualTypes
.
length
>
0
)
{
return
(
Class
<?>)
actualTypes
[
0
];
}
}
return
Object
.
class
;
}
}
src/main/java/com/cusc/adas/v2x/utils/HexStringToByteArray.java
0 → 100644
View file @
dcb9ce75
package
com.cusc.adas.v2x.utils
;
public
class
HexStringToByteArray
{
public
static
byte
[]
hexStringToByteArray
(
String
s
)
{
int
len
=
s
.
length
();
byte
[]
data
=
new
byte
[
len
/
2
];
for
(
int
i
=
0
;
i
<
len
;
i
+=
2
)
{
data
[
i
/
2
]
=
(
byte
)
((
Character
.
digit
(
s
.
charAt
(
i
),
16
)
<<
4
)
+
Character
.
digit
(
s
.
charAt
(
i
+
1
),
16
));
}
return
data
;
}
}
src/main/java/com/cusc/adas/v2x/utils/MQTTFutureClient.java
0 → 100644
View file @
dcb9ce75
package
com.cusc.adas.v2x.utils
;
import
java.net.URISyntaxException
;
import
java.util.UUID
;
import
org.fusesource.hawtbuf.Buffer
;
import
org.fusesource.mqtt.client.Future
;
import
org.fusesource.mqtt.client.FutureConnection
;
import
org.fusesource.mqtt.client.MQTT
;
import
org.fusesource.mqtt.client.Message
;
import
org.fusesource.mqtt.client.QoS
;
import
org.fusesource.mqtt.client.Topic
;
import
com.alibaba.fastjson.JSONObject
;
import
io.netty.buffer.ByteBuf
;
import
io.netty.buffer.Unpooled
;
public
class
MQTTFutureClient
{
private
final
static
String
CONNECTION_STRING
=
"tcp://172.29.128.39:32024"
;
// MQTT服务器主机地址
private
final
static
boolean
CLEAN_START
=
true
;
private
final
static
short
KEEP_ALIVE
=
30
;
// 低耗网络,但是又需要及时获取数据,心跳30s
public
final
static
long
RECONNECTION_ATTEMPT_MAX
=
6
;
public
final
static
long
RECONNECTION_DELAY
=
2000
;
public
final
static
int
SEND_BUFFER_SIZE
=
2
*
1024
*
1024
;
// 发送最大缓冲为2M
public
String
MQTTFutureClientPublic
(
JSONObject
jsBodyParameter
)
{
// 定义变量
String
jsonStr
=
""
;
// 创建MQTT对象
MQTT
mqtt
=
new
MQTT
();
try
{
String
CLIENT_ID
=
UUID
.
randomUUID
().
toString
().
replace
(
"-"
,
""
);
// 自动生成的MQTT Client Id
// 设置mqtt broker的ip和端口
mqtt
.
setHost
(
CONNECTION_STRING
);
// 连接前清空会话信息
mqtt
.
setCleanSession
(
CLEAN_START
);
// 设置重新连接的次数
mqtt
.
setReconnectAttemptsMax
(
RECONNECTION_ATTEMPT_MAX
);
// 设置重连的间隔时间
mqtt
.
setReconnectDelay
(
RECONNECTION_DELAY
);
// 设置心跳时间
mqtt
.
setKeepAlive
(
KEEP_ALIVE
);
// 设置缓冲的大小
mqtt
.
setSendBufferSize
(
SEND_BUFFER_SIZE
);
// 设置客户端id、用户名和密码
mqtt
.
setClientId
(
CLIENT_ID
);
mqtt
.
setUserName
(
"admin"
);
mqtt
.
setPassword
(
"password"
);
// 获取mqtt的连接对象BlockingConnection
final
FutureConnection
connection
=
mqtt
.
futureConnection
();
connection
.
connect
();
Topic
[]
subscribeTopics
=
{
new
Topic
(
"mqtt/face/1376464/Ack"
,
QoS
.
AT_LEAST_ONCE
)
};
// 订阅主题
connection
.
subscribe
(
subscribeTopics
);
String
publishTopic
=
"mqtt/face/1376464"
;
// 发布主题
connection
.
publish
(
publishTopic
,
jsBodyParameter
.
toString
().
getBytes
(
"UTF-8"
),
QoS
.
AT_LEAST_ONCE
,
false
);
Future
<
Message
>
futrueMessage
=
connection
.
receive
();
Message
message
=
futrueMessage
.
await
();
byte
[]
bs
=
message
.
getPayload
();
Buffer
buffer
=
message
.
getPayloadBuffer
();
ByteBuf
wrappedBuf
=
Unpooled
.
wrappedBuffer
(
bs
);
System
.
out
.
println
(
message
.
getPayloadBuffer
());
// 打印订阅的消息
String
msg
=
String
.
valueOf
(
message
.
getPayloadBuffer
());
jsonStr
=
msg
;
}
catch
(
URISyntaxException
e
)
{
e
.
printStackTrace
();
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
finally
{
}
return
jsonStr
;
}
/*
* service层调用函数,jsBodyParameter为传入的需要发布的参数
*/
public
static
String
writeToMqttMessageFuture
(
JSONObject
jsBodyParameter
)
throws
Exception
{
MQTTFutureClient
mqttFutureClient
=
new
MQTTFutureClient
();
String
messageJosn
=
mqttFutureClient
.
MQTTFutureClientPublic
(
jsBodyParameter
);
return
messageJosn
;
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
JSONObject
jsBodyParameter
=
new
JSONObject
();
// 定义发布参数变量
jsBodyParameter
.
put
(
"keyId"
,
"你好!"
);
// 设置参数值
String
response
=
writeToMqttMessageFuture
(
jsBodyParameter
);
System
.
out
.
println
(
response
);
// 打印订阅的消息
}
}
src/main/java/com/cusc/adas/v2x/utils/MqttSubscriber.java
0 → 100644
View file @
dcb9ce75
package
com.cusc.adas.v2x.utils
;
import
org.eclipse.paho.client.mqttv3.MqttClient
;
import
org.eclipse.paho.client.mqttv3.MqttConnectOptions
;
import
org.eclipse.paho.client.mqttv3.MqttException
;
public
class
MqttSubscriber
{
private
static
final
String
BROKER
=
"tcp://172.29.128.39:31883"
;
private
static
final
String
CLIENT_ID
=
"JavaSubscriber"
;
private
static
final
String
TOPIC
=
"vehicle/{vehicleId}/status"
;
public
static
void
main
(
String
[]
args
)
{
try
{
MqttClient
client
=
new
MqttClient
(
BROKER
,
CLIENT_ID
);
MqttConnectOptions
options
=
new
MqttConnectOptions
();
options
.
setCleanSession
(
true
);
client
.
connect
(
options
);
System
.
out
.
println
(
"Connected to broker: "
+
BROKER
);
client
.
subscribe
(
TOPIC
,
(
topic
,
message
)
->
{
System
.
out
.
println
(
"Received message: "
+
new
String
(
message
.
getPayload
())
+
" from topic: "
+
topic
);
});
}
catch
(
MqttException
e
)
{
e
.
printStackTrace
();
}
}
}
src/main/java/com/cusc/adas/v2x/utils/NumFlag.java
0 → 100644
View file @
dcb9ce75
package
com.cusc.adas.v2x.utils
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
@Retention
(
RetentionPolicy
.
RUNTIME
)
// 注解在运行时可用
@Target
(
ElementType
.
FIELD
)
// 注解只能用于字段(属性)
public
@interface
NumFlag
{
// 定义注解的属性
String
value
()
default
""
;
// 默认值
}
src/main/java/com/cusc/adas/v2x/utils/OffsetDef.java
0 → 100644
View file @
dcb9ce75
package
com.cusc.adas.v2x.utils
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
@Retention
(
RetentionPolicy
.
RUNTIME
)
// 注解在运行时可用
@Target
(
ElementType
.
FIELD
)
// 注解只能用于字段(属性)
public
@interface
OffsetDef
{
double
value
()
default
1
;
int
type
()
default
1
;
//1:除法 2:乘法;
int
minValidLength
()
default
0
;
}
src/main/java/com/cusc/adas/v2x/utils/Order.java
0 → 100644
View file @
dcb9ce75
package
com.cusc.adas.v2x.utils
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
@Retention
(
RetentionPolicy
.
RUNTIME
)
// 注解在运行时可用
@Target
(
ElementType
.
FIELD
)
// 注解只能用于字段(属性)
public
@interface
Order
{
int
value
();
// 定义一个名为value的属性,用于存储序号
}
src/main/java/com/cusc/adas/v2x/utils/Parse.java
0 → 100644
View file @
dcb9ce75
package
com.cusc.adas.v2x.utils
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.ParameterizedType
;
import
java.lang.reflect.Type
;
import
java.nio.ByteBuffer
;
import
java.nio.ByteOrder
;
import
java.nio.charset.StandardCharsets
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.SortedMap
;
import
java.util.TreeMap
;
import
io.netty.buffer.ByteBuf
;
import
io.netty.buffer.Unpooled
;
public
class
Parse
{
public
static
<
T
>
T
parse
(
ByteBuf
data
,
T
t
)
throws
InstantiationException
,
IllegalAccessException
,
NoSuchFieldException
,
SecurityException
,
ClassNotFoundException
{
Field
[]
fields
=
t
.
getClass
().
getDeclaredFields
();
List
<
Field
>
fList
=
new
ArrayList
<>();
SortedMap
<
Integer
,
Field
>
rstMap
=
new
TreeMap
<>();
for
(
Field
field
:
fields
)
{
field
.
setAccessible
(
true
);
if
(
field
.
isAnnotationPresent
(
Order
.
class
))
{
String
fieldName
=
field
.
getName
();
Order
order
=
field
.
getAnnotation
(
Order
.
class
);
int
num
=
order
.
value
();
//基础数据类型 且 不是数组
if
(
field
.
getType
().
isPrimitive
()
&&
!
field
.
getType
().
isArray
()
)
{
// data.re
// field.set(fList, rstMap);
readBuf
(
t
,
field
,
data
);
}
else
if
(
field
.
getClass
().
isPrimitive
()
&&
field
.
getType
().
isArray
()){
// 基础数据类型 且 是数组
}
else
if
(
List
.
class
.
isAssignableFrom
(
field
.
getType
()))
{
// 集合类型
//读取属性的注解是否引用其他字段的长度
if
(
field
.
isAnnotationPresent
(
RefNumFlag
.
class
))
{
RefNumFlag
refNumFlag
=
field
.
getAnnotation
(
RefNumFlag
.
class
);
String
refField
=
refNumFlag
.
value
();
Class
<?>
clazz1
=
t
.
getClass
();
Field
nameField
=
clazz1
.
getDeclaredField
(
refField
);
Type
genericType
=
nameField
.
getGenericType
();
nameField
.
setAccessible
(
true
);
if
(
genericType
instanceof
ParameterizedType
)
{
ParameterizedType
pt
=
(
ParameterizedType
)
genericType
;
Type
[]
actualTypes
=
pt
.
getActualTypeArguments
();
if
(
actualTypes
.
length
>
0
)
{
actualTypes
[
0
].
getClass
();
int
len
=
(
int
)
nameField
.
get
(
t
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
actualTypes
[
0
].
getClass
();
}
}
}
}
}
else
if
(
field
.
getType
()==
String
.
class
)
{
//类型为字符串
readBuf
(
t
,
field
,
data
);
}
else
{
//其他对象类型
Class
<?>
cls
=
Class
.
forName
(
field
.
getType
().
getName
());
Object
obj
=
cls
.
newInstance
();
parse
(
data
,
obj
);
field
.
set
(
t
,
obj
);
}
rstMap
.
put
(
num
,
field
);
}
}
return
t
;
}
/**
* 读取字节流
* @param t
* @param field
* @param data
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
public
static
void
readBuf
(
Object
t
,
Field
field
,
ByteBuf
data
)
throws
IllegalArgumentException
,
IllegalAccessException
{
if
(
data
.
readerIndex
()==
data
.
maxCapacity
()
)
return
;
FieldDef
fieldDef
=
null
;
if
(
field
.
isAnnotationPresent
(
FieldDef
.
class
))
{
fieldDef
=
field
.
getAnnotation
(
FieldDef
.
class
);
}
Class
<?>
type
=
field
.
getType
();
if
(
type
==
String
.
class
&&
fieldDef
!=
null
&&
fieldDef
.
type
().
equals
(
"BYTE"
))
{
byte
[]
by
=
new
byte
[
fieldDef
.
length
()];
data
.
readBytes
(
by
);
String
str
=
new
String
(
by
,
StandardCharsets
.
UTF_8
);
field
.
set
(
t
,
str
);
}
else
if
(
type
==
short
.
class
)
{
field
.
set
(
t
,
data
.
readUnsignedByte
());
}
else
if
(
type
==
int
.
class
)
{
field
.
set
(
t
,
data
.
readUnsignedShort
());
}
else
if
(
type
==
long
.
class
&&
fieldDef
==
null
)
{
field
.
set
(
t
,
data
.
readUnsignedInt
());
}
else
if
(
type
==
long
.
class
&&
fieldDef
!=
null
&&
fieldDef
.
type
().
equals
(
"TIMESTAMP"
)
&&
fieldDef
.
length
()==
8
)
{
field
.
set
(
t
,
data
.
readLong
());
}
else
if
(
type
==
long
.
class
&&
fieldDef
!=
null
&&
fieldDef
.
type
().
equals
(
"BYTE"
)
)
{
field
.
set
(
t
,
data
.
readLong
());
}
}
public
static
byte
[]
longToBytes
(
long
value
)
{
ByteBuffer
buffer
=
ByteBuffer
.
allocate
(
8
);
buffer
.
order
(
ByteOrder
.
BIG_ENDIAN
);
// 指定小端模式
buffer
.
putLong
(
value
);
// 将long值存入buffer
return
buffer
.
array
();
// 获取byte数组
}
public
static
byte
[]
longToBytes1
(
long
value
)
{
ByteBuffer
buffer
=
ByteBuffer
.
allocate
(
4
);
buffer
.
order
(
ByteOrder
.
BIG_ENDIAN
);
// 指定小端模式
buffer
.
putLong
(
value
);
// 将long值存入buffer
return
buffer
.
array
();
// 获取byte数组
}
public
static
byte
[]
intToBytes
(
int
value
)
{
ByteBuffer
buffer
=
ByteBuffer
.
allocate
(
4
);
buffer
.
order
(
ByteOrder
.
BIG_ENDIAN
);
// 指定小端模式
buffer
.
putLong
(
value
);
// 将long值存入buffer
return
buffer
.
array
();
// 获取byte数组
}
public
static
String
byteToHexString
(
byte
[]
bytes
)
{
StringBuilder
sb
=
new
StringBuilder
();
for
(
byte
b
:
bytes
)
{
sb
.
append
(
String
.
format
(
"%02x"
,
b
));
}
return
sb
.
toString
();
//return null;
// ByteBuffer buffer = ByteBuffer.allocate(8);
// buffer.order(ByteOrder.LITTLE_ENDIAN); // 指定小端模式
// buffer.putLong(value); // 将long值存入buffer
// return buffer.array(); // 获取byte数组
}
public
static
String
long2Hex
(
long
num
,
int
len
)
{
String
hex
=
Long
.
toHexString
(
num
);
int
padLength
=
len
*
2
;
if
(
hex
.
length
()
>=
padLength
)
{
return
hex
.
substring
(
hex
.
length
()
-
padLength
);
// 超长时截断
}
return
String
.
format
(
"%0"
+
padLength
+
"d"
,
0
).
replace
(
"0"
,
"0"
)
+
hex
;
// 或直接格式化
}
public
static
void
main
(
String
[]
args
)
throws
InstantiationException
,
IllegalAccessException
,
NoSuchFieldException
,
SecurityException
,
ClassNotFoundException
{
String
hexString
=
"F20000000015018cb864640000000000"
;
byte
[]
bytes
=
HexStringToByteArray
.
hexStringToByteArray
(
hexString
);
ByteBuf
byteBuf
=
Unpooled
.
buffer
(
16
);
long
l
=
500000
;
//3600000000
// 1164916946
// byte [] bs = Long.toHexString(l);
String
s
=
long2Hex
(
l
,
4
);
//longToBytes1(l);
int
i
=
990
;
String
hex
=
Integer
.
toHexString
(
i
);
String
vid
=
"T1023459"
;
byte
[]
by1
=
vid
.
getBytes
();
s
=
byteToHexString
(
by1
);
System
.
out
.
println
(
s
);
//
//
// List<Byte> byteList = new ArrayList<Byte>();
//
// Byte[] bytes = byteList.toArray(new Byte[byteList.size()]);
//byte[] bs = convoter(bytes);
//byteBuf.writeBytes(bytes);
//VehicleMessage vehicleMessage = parse(byteBuf,new VehicleMessage());
//System.out.print(vehicleMessage);
}
public
static
void
convoterBean
(
Object
source
,
Object
target
)
throws
IllegalArgumentException
,
IllegalAccessException
,
ClassNotFoundException
,
InstantiationException
,
NoSuchFieldException
,
SecurityException
{
Field
[]
fields
=
source
.
getClass
().
getDeclaredFields
();
List
<
Field
>
fList
=
new
ArrayList
<>();
SortedMap
<
Integer
,
Field
>
rstMap
=
new
TreeMap
<>();
for
(
Field
field
:
fields
)
{
field
.
setAccessible
(
true
);
Object
o
=
field
.
get
(
source
);
if
(
o
==
null
)
{
continue
;
}
OffsetDef
offsetDef
=
null
;
if
(
field
.
isAnnotationPresent
(
OffsetDef
.
class
))
{
offsetDef
=
field
.
getAnnotation
(
OffsetDef
.
class
);
}
//获取目标对象指定的属性
Field
tField
=
target
.
getClass
().
getDeclaredField
(
field
.
getName
());
tField
.
setAccessible
(
true
);
if
(
field
.
isAnnotationPresent
(
Order
.
class
))
{
if
(
field
.
getType
().
isPrimitive
()
&&
!
field
.
getType
().
isArray
()
)
{
//如果属性添加了自定义注解 offset
Class
<?>
type
=
field
.
getType
();
if
(
offsetDef
!=
null
)
{
double
offset
=
offsetDef
.
value
();
int
type1
=
offsetDef
.
type
();
int
minValidLength
=
offsetDef
.
minValidLength
();
//startindex
if
(
type
==
byte
.
class
)
{
tField
.
set
(
target
,
o
);
}
else
if
(
type
==
short
.
class
)
{
if
(
minValidLength
>
0
)
{
int
len
=
String
.
valueOf
((
Short
)
o
).
length
();
if
(
len
<
minValidLength
)
{
int
subtract
=
minValidLength
-
len
;
double
f
=(
Short
)
o
*
Math
.
pow
(
10
,
subtract
)*
offset
;
tField
.
set
(
target
,
(
float
)
f
);
}
else
{
double
f
=(
Short
)
o
*
offset
;
tField
.
set
(
target
,
(
float
)
f
);
}
}
else
{
double
f
=(
Short
)
o
*
offset
;
tField
.
set
(
target
,
(
float
)
f
);
}
}
else
if
(
type
==
int
.
class
)
{
if
(
minValidLength
>
0
)
{
int
len
=
String
.
valueOf
((
Integer
)
o
).
length
();
if
(
len
<
minValidLength
)
{
int
subtract
=
minValidLength
-
len
;
double
f
=(
Integer
)
o
*
Math
.
pow
(
10
,
subtract
)*
offset
;
tField
.
set
(
target
,
(
float
)
f
);
}
else
{
double
f
=(
Integer
)
o
*
offset
;
tField
.
set
(
target
,
(
float
)
f
);
}
}
else
{
double
f
=(
Integer
)
o
*
offset
;
tField
.
set
(
target
,
(
float
)
f
);
}
}
else
if
(
type
==
long
.
class
)
{
if
(
minValidLength
>
0
)
{
int
len
=
String
.
valueOf
((
Long
)
o
).
length
();
if
(
len
<
minValidLength
)
{
int
subtract
=
minValidLength
-
len
;
double
f
=(
Long
)
o
*
Math
.
pow
(
10
,
subtract
)*
offset
;
tField
.
set
(
target
,
(
float
)
f
);
}
else
{
double
f
=(
Long
)
o
*
offset
;
tField
.
set
(
target
,
(
float
)
f
);
}
}
else
{
double
d
=(
Long
)
o
*
offset
;
tField
.
set
(
target
,
d
);
}
}
}
else
{
tField
.
set
(
target
,
o
);
}
}
else
if
(
field
.
getClass
().
isPrimitive
()
&&
field
.
getType
().
isArray
()){
// 基础数据类型 且 是数组
}
else
if
(
List
.
class
.
isAssignableFrom
(
field
.
getType
()))
{
// 集合类型
//读取属性的注解是否引用其他字段的长度
if
(
field
.
isAnnotationPresent
(
RefNumFlag
.
class
))
{
// RefNumFlag refNumFlag = field.getAnnotation(RefNumFlag.class);
// String refField = refNumFlag.value();
// Class<?> clazz1 = t.getClass();
// Field nameField = clazz1.getDeclaredField(refField);
// Type genericType = nameField.getGenericType();
// nameField.setAccessible(true);
//
// if (genericType instanceof ParameterizedType) {
// ParameterizedType pt = (ParameterizedType) genericType;
// Type[] actualTypes = pt.getActualTypeArguments();
// if (actualTypes.length > 0) {
// actualTypes[0].getClass();
// int len= (int) nameField.get(t);
// for(int i=0;i<len;i++) {
// actualTypes[0].getClass();
// }
// }
// }
}
}
else
if
(
field
.
getType
()==
String
.
class
)
{
//类型为字符串
// try {
// String s = (String)o;
// String s1 = new String(s.getBytes());
tField
.
set
(
target
,
o
);
// }catch(Exception e) {
// e.printStackTrace();
// }
}
else
{
//其他对象类型
Class
<?>
cls
=
Class
.
forName
(
tField
.
getType
().
getName
());
Object
obj
=
cls
.
newInstance
();
convoterBean
(
o
,
obj
);
tField
.
set
(
target
,
obj
);
}
}
}
}
public
static
byte
[]
convoter
(
Byte
[]
bytes
)
{
byte
[]
bs
=
new
byte
[
bytes
.
length
];
int
i
=
0
;
for
(
Byte
b
:
bytes
)
{
bs
[
i
++]
=
b
;
}
return
bs
;
}
}
src/main/java/com/cusc/adas/v2x/utils/RefNumFlag.java
0 → 100644
View file @
dcb9ce75
package
com.cusc.adas.v2x.utils
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
@Retention
(
RetentionPolicy
.
RUNTIME
)
// 注解在运行时可用
@Target
(
ElementType
.
FIELD
)
// 注解只能用于字段(属性)
public
@interface
RefNumFlag
{
String
value
();
}
src/main/java/com/cusc/adas/v2x/utils/SM4Utils.java
0 → 100644
View file @
dcb9ce75
package
com.cusc.adas.v2x.utils
;
import
java.nio.charset.StandardCharsets
;
import
java.security.Security
;
import
java.util.Base64
;
import
javax.crypto.Cipher
;
import
javax.crypto.KeyGenerator
;
import
javax.crypto.SecretKey
;
import
javax.crypto.spec.SecretKeySpec
;
import
org.bouncycastle.jce.provider.BouncyCastleProvider
;
public
class
SM4Utils
{
private
static
final
String
ALGORITHM_NAME
=
"SM4"
;
private
static
final
String
ALGORITHM_MODE
=
"SM4/ECB/PKCS5Padding"
;
static
{
Security
.
addProvider
(
new
BouncyCastleProvider
());
}
/**
* ???? SM4 ???
* @return ????? Base64 ?????????
* @throws Exception ??
*/
public
static
String
generateKey
()
throws
Exception
{
KeyGenerator
kg
=
KeyGenerator
.
getInstance
(
ALGORITHM_NAME
,
"BC"
);
kg
.
init
(
128
);
SecretKey
secretKey
=
kg
.
generateKey
();
return
Base64
.
getEncoder
().
encodeToString
(
secretKey
.
getEncoded
());
}
/**
* SM4 ????
* @param plainText ????
* @param key ????? Base64 ?????????
* @return ????? Base64 ?????????
* @throws Exception ??
*/
public
static
String
encrypt
(
String
plainText
,
String
key
)
throws
Exception
{
byte
[]
keyBytes
=
Base64
.
getDecoder
().
decode
(
key
);
SecretKeySpec
secretKeySpec
=
new
SecretKeySpec
(
keyBytes
,
ALGORITHM_NAME
);
Cipher
cipher
=
Cipher
.
getInstance
(
ALGORITHM_MODE
,
"BC"
);
cipher
.
init
(
Cipher
.
ENCRYPT_MODE
,
secretKeySpec
);
byte
[]
encryptedBytes
=
cipher
.
doFinal
(
plainText
.
getBytes
(
StandardCharsets
.
UTF_8
));
return
Base64
.
getEncoder
().
encodeToString
(
encryptedBytes
);
}
/**
* SM4 ????
* @param cipherText ????? Base64 ?????????
* @param key ????? Base64 ?????????
* @return ????
* @throws Exception ??
*/
public
static
String
decrypt
(
String
cipherText
,
String
key
)
throws
Exception
{
byte
[]
keyBytes
=
Base64
.
getDecoder
().
decode
(
key
);
SecretKeySpec
secretKeySpec
=
new
SecretKeySpec
(
keyBytes
,
ALGORITHM_NAME
);
Cipher
cipher
=
Cipher
.
getInstance
(
ALGORITHM_MODE
,
"BC"
);
cipher
.
init
(
Cipher
.
DECRYPT_MODE
,
secretKeySpec
);
byte
[]
cipherBytes
=
Base64
.
getDecoder
().
decode
(
cipherText
);
byte
[]
decryptedBytes
=
cipher
.
doFinal
(
cipherBytes
);
return
new
String
(
decryptedBytes
,
StandardCharsets
.
UTF_8
);
}
}
src/main/java/com/cusc/adas/v2x/vo/AutomaticDriveInfo.java
0 → 100644
View file @
dcb9ce75
package
com.cusc.adas.v2x.vo
;
import
java.util.List
;
import
com.cusc.adas.v2x.utils.NumFlag
;
import
com.cusc.adas.v2x.utils.Order
;
import
com.cusc.adas.v2x.utils.RefNumFlag
;
/**
* 车辆自动驾驶信息
* @author huangml
*
*/
public
class
AutomaticDriveInfo
{
//执行云端控制命令编号
@Order
(
1
)
private
long
cloudMessageId
;
//自动驾驶需求加速度
@Order
(
2
)
private
int
accelCmd
;
//自动驾驶需求扭矩
@Order
(
3
)
private
long
torqueCmd
;
//自动驾驶需求速度
@Order
(
4
)
private
int
velocityCmd
;
//规划-位置点轨 迹数量
@Order
(
5
)
@NumFlag
private
int
planningLocNum
;
//规划-位置点轨 迹列表
@Order
(
6
)
@RefNumFlag
(
value
=
"planningLocNum"
)
private
List
<
TracePoint
>
planningLocs
;
//决策-换道
@Order
(
7
)
private
short
decisionLaneChange
;
//加减速
@Order
(
8
)
private
short
decisionAccel
;
//决策-转向
@Order
(
9
)
private
short
decisionTurnSignal
;
//决策-车辆状态
@Order
(
10
)
private
short
decisionVehicleStatus
;
//感知目标个数
@Order
(
11
)
@NumFlag
private
short
detectionLen
;
//感知目标数据
@RefNumFlag
(
value
=
"detectionLen"
)
@Order
(
12
)
private
List
<
TrajectoryInfo
>
detectionData
;
//自动驾驶系统故障
@Order
(
13
)
private
int
autoDrivingSysFault
;
//电子手刹状态
@Order
(
14
)
private
short
epbFlag
;
//自定义字段长度
@Order
(
15
)
private
short
userdefinedDataLength
;
//自定义字段内容
@Order
(
16
)
private
byte
[]
userdefinedData
;
}
src/main/java/com/cusc/adas/v2x/vo/Cov.java
0 → 100644
View file @
dcb9ce75
package
com.cusc.adas.v2x.vo
;
public
class
Cov
{
private
long
cov
;
// 状态量协方差
public
long
getCov
()
{
return
cov
;
}
public
void
setCov
(
long
cov
)
{
this
.
cov
=
cov
;
}
}
Prev
1
2
3
4
5
6
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment