2025-01-02 02:25:42 +08:00
|
|
|
|
extends Node3D
|
|
|
|
|
|
|
|
|
|
@onready var view_camera: Camera3D = %ViewCamera
|
|
|
|
|
@onready var side_display_sub_viewport: SubViewport = $SideDisplaySubViewport
|
|
|
|
|
@onready var main_sub_viewport: SubViewport = $MainSubViewport
|
2025-01-13 14:39:58 +08:00
|
|
|
|
@onready var vertical: Node3D = %Vertical
|
|
|
|
|
@onready var camera_3d: Node3D = %Camera3D
|
2025-01-02 02:25:42 +08:00
|
|
|
|
|
|
|
|
|
func _init() -> void:
|
|
|
|
|
Global.EgoVehicle3D = self
|
2025-01-13 14:39:58 +08:00
|
|
|
|
|
|
|
|
|
func _ready() -> void:
|
|
|
|
|
Websocket.connected_to_server.connect(connected_to_server)
|
|
|
|
|
Websocket.message_received.connect(message_received)
|
2025-01-02 02:25:42 +08:00
|
|
|
|
func SideDisplayGetTexture():
|
|
|
|
|
return side_display_sub_viewport.get_texture()
|
|
|
|
|
func MainSubGetTexture():
|
|
|
|
|
return main_sub_viewport.get_texture()
|
2025-01-13 14:39:58 +08:00
|
|
|
|
func connected_to_server():
|
|
|
|
|
pose()
|
|
|
|
|
pass
|
|
|
|
|
var actuation_status = 0
|
|
|
|
|
var mb_post = Vector3(0,0,0)
|
|
|
|
|
var mb_rotation = Vector3(0,0,0)
|
2025-01-13 17:53:01 +08:00
|
|
|
|
var js = 360
|
2025-01-13 14:39:58 +08:00
|
|
|
|
func message_received(data: Dictionary):
|
|
|
|
|
if data.is_empty():
|
|
|
|
|
return
|
|
|
|
|
if !data.has("topic"):return
|
|
|
|
|
|
|
|
|
|
match data.topic:
|
2025-01-13 17:53:01 +08:00
|
|
|
|
"/hmi_input/app/cloud_control_platform/vehicle_info":
|
|
|
|
|
if data.msg.head_light == 1:
|
|
|
|
|
%polySurface14.set("surface_material_override/0",preload("res://Headlight.tres"))
|
|
|
|
|
%polySurface15.set("surface_material_override/0",preload("res://Headlight.tres"))
|
|
|
|
|
%polySurface16.set("surface_material_override/0",preload("res://Headlight.tres"))
|
|
|
|
|
%polySurface17.set("surface_material_override/0",preload("res://Headlight.tres"))
|
|
|
|
|
%polySurface26.set("surface_material_override/0",preload("res://Headlight.tres"))
|
|
|
|
|
%polySurface30.set("surface_material_override/0",preload("res://Headlight.tres"))
|
|
|
|
|
else:
|
|
|
|
|
%polySurface14.set("surface_material_override/0",null)
|
|
|
|
|
%polySurface15.set("surface_material_override/0",null)
|
|
|
|
|
%polySurface16.set("surface_material_override/0",null)
|
|
|
|
|
%polySurface17.set("surface_material_override/0",null)
|
|
|
|
|
%polySurface26.set("surface_material_override/0",null)
|
|
|
|
|
%polySurface30.set("surface_material_override/0",null)
|
|
|
|
|
#转向灯
|
|
|
|
|
if data.msg.turn_light == 1:
|
|
|
|
|
%polySurface14.set("surface_material_override/0",preload("res://TurnSignal.tres"))
|
|
|
|
|
%polySurface15.set("surface_material_override/0",preload("res://TurnSignal.tres"))
|
|
|
|
|
%polySurface16.set("surface_material_override/0",null)
|
|
|
|
|
%polySurface17.set("surface_material_override/0",null)
|
|
|
|
|
elif data.msg.turn_light == 2:
|
|
|
|
|
%polySurface16.set("surface_material_override/0",preload("res://TurnSignal.tres"))
|
|
|
|
|
%polySurface17.set("surface_material_override/0",preload("res://TurnSignal.tres"))
|
|
|
|
|
%polySurface14.set("surface_material_override/0",null)
|
|
|
|
|
%polySurface15.set("surface_material_override/0",null)
|
|
|
|
|
pass
|
|
|
|
|
if data.msg.brk>0:
|
|
|
|
|
%polySurface26.set("surface_material_override/0",preload("res://Brake.tres"))
|
|
|
|
|
%polySurface30.set("surface_material_override/0",preload("res://Brake.tres"))
|
|
|
|
|
else:
|
|
|
|
|
%polySurface26.set("surface_material_override/0",null)
|
|
|
|
|
%polySurface30.set("surface_material_override/0",null)
|
|
|
|
|
actuation_status = data.msg.thr
|
2025-01-13 14:39:58 +08:00
|
|
|
|
"/localization/pose_twist_fusion_filter/pose":
|
|
|
|
|
var post = data.msg.pose
|
|
|
|
|
mb_post = Vector3(post.position.x, post.position.z, -post.position.y)
|
|
|
|
|
mb_rotation = quaternion_to_euler(Quaternion(post.orientation.x,post.orientation.y,post.orientation.z,post.orientation.w))
|
2025-01-13 17:53:01 +08:00
|
|
|
|
"/vehicle/status/steering_status":
|
|
|
|
|
var max_angle = 30
|
|
|
|
|
var min_angle = -30
|
|
|
|
|
var actual_angle = -data.msg.steering_tire_angle
|
|
|
|
|
#print(data.msg.steering_tire_angle)
|
|
|
|
|
%polySurface31.rotation.y = actual_angle
|
|
|
|
|
%polySurface33.rotation.y = -actual_angle
|
|
|
|
|
%Q1_23.rotation.y = actual_angle
|
|
|
|
|
%Q1_22.rotation.y = actual_angle
|
|
|
|
|
#$EgoVehicle/robobus_a21_v11/robobus/wheel/Back_left.rotation.y = actual_angle
|
|
|
|
|
#$EgoVehicle/robobus_a21_v11/robobus/wheel/Back_right.rotation.y = actual_angle
|
|
|
|
|
#$EgoVehicle/robobus_a21_v11/robobus/wheel/Front_left.rotation.y = -actual_angle
|
|
|
|
|
#$EgoVehicle/robobus_a21_v11/robobus/wheel/Front_right.rotation.y = -actual_angle
|
|
|
|
|
|
|
|
|
|
#$EgoVehicle/robobus_a21_v11/robobus/mudguard/mudguard_001.rotation.y = -actual_angle + 3.1316
|
|
|
|
|
#$EgoVehicle/robobus_a21_v11/robobus/mudguard/mudguard_002.rotation.y = -actual_angle + 3.1316
|
|
|
|
|
#$EgoVehicle/robobus_a21_v11/robobus/mudguard/mudguard_003.rotation.y = actual_angle + 3.1316
|
|
|
|
|
#$EgoVehicle/robobus_a21_v11/robobus/mudguard/mudguard_004.rotation.y = actual_angle + 3.1316
|
|
|
|
|
var jd = 360
|
|
|
|
|
func xz(delta):
|
|
|
|
|
jd -= delta
|
|
|
|
|
if jd <= 0:
|
|
|
|
|
jd = 360
|
|
|
|
|
var arr = [%Q1_23, %Q1_17, %Q1_22, %Q1_21]
|
|
|
|
|
|
|
|
|
|
for item in arr:
|
|
|
|
|
item.rotation_degrees.z = jd * -1
|
2025-01-13 14:39:58 +08:00
|
|
|
|
func _process(delta):
|
2025-01-13 17:53:01 +08:00
|
|
|
|
xz(delta*500*actuation_status)
|
2025-01-13 14:39:58 +08:00
|
|
|
|
if mb_post.distance_to(global_position) > 10:
|
|
|
|
|
global_position = mb_post
|
|
|
|
|
rotation = mb_rotation
|
|
|
|
|
else:
|
|
|
|
|
global_position = lerp(global_position,mb_post,1*delta)
|
|
|
|
|
rotation.x = lerp_angle(rotation.x,mb_rotation.x,1*delta)
|
|
|
|
|
rotation.y = lerp_angle(rotation.y,mb_rotation.y,1*delta)
|
|
|
|
|
rotation.z = lerp_angle(rotation.z,mb_rotation.z,1*delta)
|
|
|
|
|
|
|
|
|
|
#xz(delta*500*actuation_status)
|
|
|
|
|
|
|
|
|
|
%Camera3D.global_position = global_position
|
|
|
|
|
#%Camera3D.global_position.z = global_position.z
|
|
|
|
|
#%Camera3D.global_position.y = global_position.y
|
|
|
|
|
%Camera3D.global_rotation_degrees.y = global_rotation_degrees.y - 90
|
|
|
|
|
#$SubViewport2/Camera3D.global_transform = %ViewCamera.global_transform
|
|
|
|
|
|
|
|
|
|
func pose():#
|
|
|
|
|
var send_data = {
|
|
|
|
|
"op": "subscribe",
|
|
|
|
|
"topic": "/localization/pose_twist_fusion_filter/pose",
|
|
|
|
|
"type": "geometry_msgs/msg/PoseStamped"
|
|
|
|
|
}
|
|
|
|
|
print("post请求发送")
|
|
|
|
|
Websocket.send_msg(str(send_data))
|
|
|
|
|
# 将四元数转换为欧拉角(roll, pitch, yaw)
|
|
|
|
|
func quaternion_to_euler(quaternion: Quaternion) -> Vector3:
|
|
|
|
|
var roll: float
|
|
|
|
|
var pitch: float
|
|
|
|
|
var yaw: float
|
|
|
|
|
|
|
|
|
|
# 计算四元数分量的平方
|
|
|
|
|
var sqx = quaternion.x * quaternion.x
|
|
|
|
|
var sqy = quaternion.y * quaternion.y
|
|
|
|
|
var sqz = quaternion.z * quaternion.z
|
|
|
|
|
var sqw = quaternion.w * quaternion.w
|
|
|
|
|
|
|
|
|
|
# 计算sarg,它代表pitch的sin值
|
|
|
|
|
var sarg = -2 * (quaternion.x * quaternion.z - quaternion.w * quaternion.y)
|
|
|
|
|
var pi_2 = PI/2 # π/2,表示90度的弧度值
|
|
|
|
|
|
|
|
|
|
# 处理万向节锁情况
|
|
|
|
|
if sarg <= -0.99999:
|
|
|
|
|
pitch = -pi_2 # pitch设为-90度
|
|
|
|
|
roll = 0 # roll设为0
|
|
|
|
|
yaw = 2 * atan2(quaternion.x, -quaternion.y) # 计算yaw角
|
|
|
|
|
elif sarg >= 0.99999:
|
|
|
|
|
pitch = pi_2 # pitch设为90度
|
|
|
|
|
roll = 0 # roll设为0
|
|
|
|
|
yaw = 2 * atan2(-quaternion.x, quaternion.y) # 计算yaw角
|
|
|
|
|
else:
|
|
|
|
|
# 在一般情况下,计算pitch, roll和yaw
|
|
|
|
|
pitch = asin(sarg)
|
|
|
|
|
roll = atan2(2 * (quaternion.y * quaternion.z + quaternion.w * quaternion.x), sqw - sqx - sqy + sqz)
|
|
|
|
|
yaw = atan2(2 * (quaternion.x * quaternion.y + quaternion.w * quaternion.z), sqw + sqx - sqy - sqz)
|
|
|
|
|
|
|
|
|
|
# 返回欧拉角,作为一个Vector3对象
|
|
|
|
|
return Vector3(roll, yaw, pitch)
|