先看最终目标ROS2机器人系统 │ ros2 launch │ ┌──────────┼──────────┐ ↓ ↓ ↓ Node A Node B Node C │ │ │ └────── Topic / Service ──────┘ │ 数据和命令流动 │ ┌──────────────┼──────────────┐ ↓ ↓ ↓ TF2 URDF ros2_control │ │ │ ↓ ↓ ↓ 坐标关系 机器人模型 控制器 │ ↓ Hardware Interface │ ↓ EtherCAT/CAN │ ↓ 电机你现在先不要研究每一个节点怎么写。先搞清楚启动 → 数据 → 坐标 → 控制 → 硬件这条主线。1、第一层Bringup真实机器人 ROS2 项目里面你以后经常看到robot_bringup或者xxx_bringup这个名字非常值得记。它通常不是一个核心算法包而是负责把整个机器人系统启动起来。比如robot_bringup/ ├── launch/ │ ├── robot.launch.py │ ├── simulation.launch.py │ └── hardware.launch.py │ └── config/ ├── controller.yaml └── robot.yaml于是ros2 launch robot_bringup robot.launch.py可能一次启动robot_state_publisher controller_manager joint_state_broadcaster robot_controller RViz hardware_interface所以以后看到bringup你脑子里直接翻译成系统启动入口。2、第二层URDF——机器人“长什么样”现在假设机器人已经启动ROS2 需要知道机器人有多少个关节 每个关节连接什么 每个 link 多大 坐标系在哪里 关节怎么运动这就是URDF例如一个简单机械臂base_link │ joint1 │ link1 │ joint2 │ link2 │ joint3 │ link3URDF 描述的是Link Joint 几何模型 惯量 碰撞模型 关节限制真实机器人 URDF 往往很长。例如几十个关节left_hip left_knee left_ankle right_hip right_knee right_ankle ...直接写 URDF 很麻烦。所以工程里经常看到.xacro你可以暂时把它理解成更方便生成 URDF 的模板语言。因此以后看到urdf/ ├── robot.urdf.xacro ├── leg.xacro ├── arm.xacro └── sensor.xacro不要懵。本质上Xacro ↓ 生成 ↓ URDF ↓ 机器人描述3、第三层robot_state_publisher这是一个非常重要的 Node。它的任务可以简单理解为根据机器人模型和关节状态告诉 ROS2 每个 link 当前在哪里。例如base_link ↓ left_hip ↓ left_thigh ↓ left_knee ↓ left_shank如果膝关节转了joint position变化 ↓ robot_state_publisher ↓ TF变化 ↓ RViz里的机器人姿态变化4、TF2机器人坐标系的“关系网络”你可以把 TF2 理解成机器人所有坐标系之间的关系管理系统。例如人形机器人base_link │ ├── torso │ ├── left_leg │ ├── left_thigh │ ├── left_shin │ └── left_foot │ └── right_leg ├── right_thigh ├── right_shin └── right_foot相机head │ └── camera_linkIMUtorso │ └── imu_linkTF2 就是在维护camera_link ↓ head ↓ torso ↓ base_link这样的坐标关系。5、ros2_control到这里URDF ↓ 机器人是什么样TF2 ↓ 机器人各部分在哪里但是还缺一个东西怎么让机器人动这就是ros2_control你可以先把它理解成ROS2 和真实机器人硬件之间的标准控制框架。整体ROS2 │ Controller │ ↓ ros2_control │ Hardware Interface │ ┌───────┴───────┐ ↓ ↓ EtherCAT CAN ↓ ↓ 电机 电机所以Controller负责我要机器人怎么运动。而Hardware Interface负责怎么把这个运动命令真正送给电机。现在把整条链真正串起来你现在应该能看懂下面这个架构robot_bringup │ Launch启动 │ ┌──────────────┼──────────────┐ ↓ ↓ ↓ GMR robot_state controller Node publisher manager │ │ │ ↓ ↓ ↓ /joint_command TF2 ros2_control │ ↓ Hardware Interface │ ┌───────┴───────┐ ↓ ↓ MuJoCo EtherCAT │ │ ↓ ↓ 仿真 真实机器人旁边URDF/Xacro ↓ 机器人模型 ↓ robot_state_publisher ↓ TF2而参数YAML ↓ Controller / GMR / Driver最终Launch ↓ 把所有东西启动起来6、你现在看真实 ROS2 仓库应该按照这个顺序以后打开一个陌生机器人项目不要从.cpp开始。按照① README ↓ ② Workspace ↓ ③ Package ↓ ④ bringup ↓ ⑤ launch ↓ ⑥ config/YAML ↓ ⑦ URDF/Xacro ↓ ⑧ Node ↓ ⑨ Topic ↓ ⑩ TF2 ↓ ⑪ Controller ↓ ⑫ ros2_control ↓ ⑬ Hardware这就是你现在最需要建立的读 ROS2 项目的方法论。ROS2 为什么需要 URDF因为 ROS2 本身并不知道“你的机器人到底长什么样”比如宇树 G1head │ torso │ pelvis / \ left_leg right_leg │ │ foot footROS2 需要知道有哪些关节有哪些身体部件谁连接谁关节能不能转能转多少每个部件的坐标系在哪里碰撞模型是什么质量、惯量是什么这就是URDF主要解决的问题。你只需要先记住URDF 机器人结构说明书它描述的是机器人本身。例如机器人 │ ├── base_link │ ├── pelvis │ ├── torso │ ├── left_arm │ ├── right_arm │ ├── left_leg │ └── right_leg这些叫Link也就是机器人的“身体部件”。7、Link 是什么非常简单Link 一块刚体例如大腿 小腿 脚 手臂 前臂 手 躯干都可以看成 Link。例如大腿 ↓ 小腿 ↓ 脚可以理解成Link ↓ Joint ↓ Link ↓ Joint ↓ Link8、Joint 是什么Joint 就是两个 Link 之间怎么连接、怎么运动。例如机器人腿大腿 │ │ 髋关节 ↓ 小腿 │ │ 膝关节 ↓ 脚对应thigh │ hip_joint │ shin │ knee_joint │ foot所以Link 是东西Joint 是东西之间的连接和运动关系。这个一定记住。Joint 有哪些类型目前最需要知道三个1. Fixed固定连接torso │ fixed │ camera摄像头固定在头上就可以是 Fixed。2. Revolute旋转关节。机器人绝大部分关节都属于这一类。例如大腿 │ 髋关节 ↻ │ 小腿3. Prismatic直线运动←────→机器人传统机械臂里可能比较常见。对于你现在的 humanoid 运控工作重点理解 Fixed Revolute 就够了。Xacro 帮你生成 URDF 的模板语言你可以理解成Xacro ↓ 生成 ↓ URDF所以URDF 是最终机器人模型Xacro 是更方便写 URDF 的方式。9、robot_state_publisher现在我们有了URDF ↓ 知道机器人有哪些 Link / Joint但是还有一个问题机器人现在的关节到底转到了哪里比如左膝关节 30°那么小腿应该在哪里这时候就需要robot_state_publisher它的作用可以简单理解成URDF Joint State ↓ 计算 ↓ 各个 Link 的空间关系 ↓ 发布 TF10、TF2TF2 管理机器人各个坐标系之间空间关系的系统。例如base_link ↓ pelvis ↓ torso ↓ head ↓ camera_linkTF2 就是在告诉 ROS2camera_link 相对于 head 在哪里 head 相对于 torso 在哪里 torso 相对于 base_link 在哪里机器人学ROS2连杆Link关节Joint坐标系TF Frame坐标变换TF Transform机器人结构URDF参数化机器人模型Xacro根据关节状态计算 TFrobot_state_publisher这个地方非常重要。Joint State告诉你左膝 position 0.5 rad velocity ... effort ...它描述的是关节状态TF告诉你left_foot 相对于 base_link 在哪里它描述的是坐标系之间的位置和姿态关系所以Joint State ↓ 关节转了多少 ↓ robot_state_publisher ↓ TF ↓ 各个坐标系在哪里11、RViz以后打开rviz2你会看到机器人模型。背后的逻辑其实就是URDF ↓ Robot Model ↓ TF ↓ RViz ↓ 显示机器人所以 RViz 不是什么“神奇的机器人软件”。它主要是在把 ROS2 中的数据可视化出来。URDF / Xacro │ 机器人结构模型 │ Link Joint │ ↓ robot_state_publisher │ ↓ TF2 │ 各坐标系之间的空间关系 │ ↓ RViz Joint State ───────┘而控制链是另外一条GMR ↓ Joint Command ↓ Controller ↓ ros2_control ↓ Hardware Interface ↓ EtherCAT ↓ 电机两条线最后共同组成一个机器人系统。12、Static TF 和 Dynamic TF这个也不用学复杂。Static TF不会变化。例如head ↓ camera_link摄像头牢牢固定在头上。那么head → camera_link基本不会变化。这就是静态 TF。Dynamic TF会随着机器人运动变化。例如torso ↓ upper_arm ↓ forearm ↓ hand手臂动起来以后torso → hand一直在变化。所以这是动态 TF以后调机器人系统你会经常用。查看 TFros2 topic echo /tf静态 TFros2 topic echo /tf_static查看节点ros2 node list查看机器人状态ros2 topic echo /joint_states查看 TF 树ros2 run tf2_tools view_frames查看两个坐标系之间的关系ros2 run tf2_ros tf2_echo base_link camera_link不用死记以后真正调系统的时候再查命令即可。13、ros2_controlROS2 │ ↓ Controller │ ↓ ros2_control │ ┌────────┴────────┐ ↓ ↓ Command Interface State Interface ↓ ↑ └──── Hardware ───┘ │ ↓ Hardware Interface │ ┌────────┴────────┐ ↓ ↓ EtherCAT MuJoCo ↓ ↓ 电机 仿真上面 控制算法 ↓ Controller ↓ ros2_control ↓ Hardware Interface ↓ 具体硬件所以上面的控制逻辑尽量不要关心底层电机到底是 EtherCAT、CAN 还是仿真。底层通过 Hardware Interface 对接。Controller它不希望知道“下面到底是 EtherCAT 还是 MuJoCo”所以Controller ↓ ros2_control ↓ Hardware Interface ↓ 具体硬件例如真机Controller ↓ ros2_control ↓ G1 Hardware Interface ↓ EtherCAT ↓ 电机仿真Controller ↓ ros2_control ↓ Simulation Interface ↓ MuJoCo上面的 Controller 可以保持基本一致。这就是 ros2_control 很重要的意义。14、 Hardware Interface简单理解Hardware Interface ROS2 和真实硬件之间的翻译层。上面说左膝目标位置 0.5 radHardware Interface 负责把这个东西变成底层硬件能理解的东西。例如ROS2 ↓ position command ↓ Hardware Interface ↓ EtherCAT PDO ↓ 电机驱动器 ↓ 电机然后电机反馈编码器 ↓ EtherCAT ↓ Hardware Interface ↓ ROS2 ↓ joint_state于是形成闭环Command ↓ ROS2 → Hardware → 电机 ↑ FeedbackJoint Command ↓ Controller ↓ ros2_control ↓ Hardware Interface ↓ EtherCAT ↓ Motor ↓ Encoder ↓ Hardware Interface ↓ Joint State ↓ ROS2所以你会发现ROS2 并没有改变机器人控制的本质。它主要是在把整个机器人软件系统组织起来。名称大白话Controller决定机器人应该怎么动ros2_control控制框架Hardware InterfaceROS2 和硬件之间的翻译层Command Interface给硬件的目标State Interface硬件反馈回来的状态这五个概念搞明白后面学习就会非常顺。15、 Controller 到底怎么控制关节你现在最需要搞明白的是这一条上层算法 ↓ Controller ↓ Command Interface ↓ Hardware Interface ↓ 电机以及反馈编码器 ↓ Hardware Interface ↓ State Interface ↓ ControllerController 不等于“电机控制器”这是刚接触 ros2_control 很容易混淆的地方。这里的Controller更接近ROS2 中负责产生关节控制目标的软件模块。例如Joint Trajectory Controller收到左膝 → 0.5 rad 右膝 → 0.6 rad然后产生对应的关节命令。真正和电机通信的是后面的Hardware Interface所以Controller 算“我要什么” Hardware Interface 想办法把这个要求送到硬件16、 Command Interface假设一个关节left_knee可能存在position velocity effort这就是不同的Command Interface。例如position command意思“我希望这个关节到这个位置。”或者velocity command意思“我希望这个关节以这个速度运动。”或者effort command意思“我希望给这个关节这个力/力矩控制量。”你可以把它理解成Controller ↓ “给左膝 0.5 rad” ↓ position command interface17、 State Interface反过来机器人会告诉 ROS2left_knee position 0.48 left_knee velocity 0.12 left_knee effort ...这些就是State Interface所以Command Interface ↓ 输出 ↓ Hardware ↑ 反馈 ↑ State Interface这是 ros2_control 最核心的一组概念。18、 Controller Manager现在再加入一个东西Controller Manager它可以理解成Controller 的管理者。例如你的机器人可能同时有joint_state_broadcaster arm_controller leg_controller head_controllerController Manager 负责加载 Controller启动 Controller停止 Controller切换 Controller管理 Controller 使用哪些接口所以结构变成Controller Manager / | \ ↓ ↓ ↓ Controller Controller Controller ↓ ros2_control ↓ Hardware Interface假设控制频率500 Hz一个周期大致可以理解成① 读取硬件反馈 ↓ ② 更新 State Interface ↓ ③ Controller 读取状态 ↓ ④ Controller 计算 ↓ ⑤ 产生 Command Interface ↓ ⑥ Hardware Interface 写入硬件 ↓ ⑦ 电机执行 ↓ ⑧ 编码器反馈 ↓ 回到①形成闭环┌──────────────────────┐ │ ↓ 反馈 → State → Controller → Command ↑ ↓ └──── Hardware ←──────────┘这就是你之前学的闭环控制在 ROS2 中的一个软件实现形式。上层算法 ↓ Joint Target ↓ Controller ↓ Command Interface ↓ ros2_control ↓ Hardware Interface ↓ EtherCAT/CAN ↓ 电机 ↑ Encoder ↑ State Interface ↑ ros2_controlController 是什么→ 产生控制目标的软件模块。Command Interface 是什么→ 向硬件发送什么类型的控制命令。State Interface 是什么→ 从硬件读取什么状态。Controller Manager 是什么→ 管理 Controller 的加载、启动、停止和切换。19、 Hardware Interface你可以把它理解成一个“适配器”ROS2世界 ↓ Command / State Interface ↓ Hardware Interface ↓ 机器人硬件世界上面只认识position velocity effort下面可能是EtherCAT PDO CAN 串口 SDK MuJoCo所以 Hardware Interface 的任务就是把 ROS2 的标准接口翻译成具体硬件能理解的通信。read()从机器人读取状态电机 ↓ EtherCAT ↓ Hardware Interface ↓ read() ↓ State Interface ↓ ROS2例如position 0.52 velocity 0.13 effort ...write()把 ROS2 的目标写给机器人Controller ↓ Command Interface ↓ write() ↓ Hardware Interface ↓ EtherCAT ↓ 电机例如left_knee position command 0.6所以你可以直接记read 从硬件读write 向硬件写Controller │ ↓ Command Interface │ ↓ Hardware Interface │ write │ ↓ EtherCAT │ ↓ 电机驱动 │ ↓ 电机 │ 编码器 │ ↓ EtherCAT │ read │ ↓ Hardware Interface │ ↓ State Interface │ ↓ Controller20、 以后遇到机器人“不动”你应该怎么想不要第一反应就怀疑电机。按照链路检查① Controller启动了吗 ↓ ② Controller有没有产生Command ↓ ③ Command Interface存在吗 ↓ ④ Hardware Interface激活了吗 ↓ ⑤ write()有没有执行 ↓ ⑥ EtherCAT有没有发送 ↓ ⑦ 驱动器有没有收到 ↓ ⑧ 电机有没有执行反馈则反过来电机 ↓ 编码器 ↓ EtherCAT ↓ read() ↓ State Interface ↓ ROS2沿着数据链逐段定位而不是一上来猜问题。21、 Noitom和宇树G1完整机器人系统先看最终全貌人体 ↓ Motion Capture / \ Xsens Noitom \ / ↓ ↓ MotionInput ↓ NoitomFrame ↓ GMR ↓ Joint Target ↓ Controller ↓ ros2_control ↓ Hardware Interface ↓ ┌───────┴────────┐ ↓ ↓ EtherCAT MuJoCo ↓ ↓ G1 真机 仿真1. Motion Capture 层Xsens / Noitom ↓ 人体骨骼运动数据例如人体左手在哪里 人体膝盖怎么弯 人体躯干怎么旋转这些数据本质上是人体运动状态。2. MotionInput你之前已经做过这个抽象XsensUdpSource ↓ NoitomFrame或者NoitomMocapApiSource ↓ NoitomFrame所以 GMR 不需要关心“数据到底来自 Xsens 还是 Noitom”它只需要NoitomFrame这就是软件工程里面非常典型的接口抽象 多种实现。3. GMR然后NoitomFrame ↓ GMR ↓ Robot Joint Target这里发生的是人体动作 → 机器人动作例如人体膝盖角度 ↓ 机器人腿部目标关节角所以 GMR 属于运动重定向 / IK / 运动映射层。它不是EtherCAT电机驱动ControllerHardware Interface这些东西不要混。4. Joint Target 到 ControllerGMR 算出来q_target [ q1, q2, q3, ... ]这个东西进入控制系统。可以理解为GMR ↓ “我希望机器人每个关节到这些位置”然后 Controller 再负责目标 ↓ 控制逻辑 ↓ 输出控制命令5. ros2_control接下来Controller ↓ ros2_control这里的核心作用已经学过把上层控制和底层硬件解耦。于是上面不需要关心EtherCAT PDO CAN 驱动器寄存器 编码器协议这些交给下面。6. Hardware Interface继续ros2_control ↓ Hardware InterfaceHardware Interface 把position command velocity command effort command转换成底层硬件需要的数据。例如Command ↓ write() ↓ EtherCAT PDO反馈EtherCAT PDO ↓ read() ↓ Joint State7. 真机路线于是完整真机链路就是人体 ↓ 动捕 ↓ NoitomFrame ↓ GMR ↓ Joint Target ↓ Controller ↓ ros2_control ↓ Hardware Interface ↓ EtherCAT ↓ 电机 ↓ 编码器 ↓ EtherCAT ↓ Hardware Interface ↓ Joint State ↓ Controller这就是一个完整闭环。8. MuJoCo 路线如果换成仿真人体 ↓ 动捕 ↓ GMR ↓ Joint Target ↓ Controller ↓ ros2_control ↓ Simulation Hardware ↓ MuJoCo因此你之前使用 MuJoCo 的经验现在就接上了。你可以把真实 Hardware Interface换成仿真 Hardware Interface上层控制逻辑仍然可以保持一致。9. 那么 ROS2 在整个系统中到底是什么ROS2 更像整个机器人软件系统的通信 节点组织 参数配置 启动管理 控制框架集成平台。所以你可以把整个系统看成┌─────────────────────────────┐ │ ROS2 │ │ │ │ Motion Capture │ │ ↓ │ │ GMR │ │ ↓ │ │ Controller │ │ ↓ │ │ ros2_control │ │ ↓ │ │ Hardware Interface │ └────────────┬────────────────┘ ↓ EtherCAT ↓ G122、 以后拿到一个陌生 ROS2 机器人项目怎么办这是这套学习路线最终要达到的能力。不要一上来就看源码。先找这几个东西第一启动入口找launch/ bringup/问系统怎么启动第二机器人模型找urdf/ xacro/问机器人结构是什么第三控制器找controller/ config/ yaml问谁产生控制命令第四硬件找hardware/ hardware_interface/问ROS2 怎么连接真实机器人第五上层算法找gmr/ ik/ motion/ planner/问机器人为什么要这么运动第六通信找msg/ srv/ action/ topic问数据怎么流动看到robot_bringup robot_description robot_controller robot_hardware gmr xxx_msgs你应该能大概判断robot_bringup → 系统启动 robot_description → URDF/Xacro robot_controller → 控制器 robot_hardware → 硬件接口 gmr → 运动重定向 xxx_msgs → ROS2数据接口然后再进入源码。
企业数字化 ERP 产品动态
相关推荐
耐溶剂标签怎么选?哑银PET面材、耐化学胶与树脂碳带打印落地 危化品仓库、实验室、化工车间的标签,和办公室里的标签不是一回事。一张贴在溶剂桶、试剂瓶、配电柜上的标签,每天面对的不只是扫码枪,还有碱液飞溅、有机溶剂擦拭、高温烘烤和叉车搬运的剐蹭。标签一旦字迹模糊、边角起翘,轻则重… · 2026/9/24 17:35:25
【C/C++ 宽窄字符详解:char、wchar_t 的原理、编码关系与跨平台互转】 🔥 个人主页: flos chen ❄️ 个人专栏: 《系统分析师》 《C/C》 《Qt》 《Linux》 《SQL》 《深度学习》 🌟 边学习,边记录,一起学习进步! 文章目录一、引言:一段… · 2026/9/24 17:35:25
全局可控与精细化分类:知源 AI 分级系统赋能教育数据治理落地方案 一、方案概要:AI驱动教育数据精细化治理,实现全域可控与高效落地提示:本方案基于教育数据治理合规要求与业务痛点,依托AI技术构建全流程治理体系,实现数据管控、治理效率、分类精度的三维升级。随着教育数字化深度落地… · 2026/9/24 17:35:13
基于SpringBoot的宠物救助及领养平台的设计与实现-附源码 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台… · 2026/9/24 18:13:46
Unity 2D格斗游戏动画系统实战:从.anim文件到可维护状态机 简介:本资源是一套基于Unity引擎开发2D街机游戏《三国战纪》的完整教学实践项目,面向Unity初学者及有一定C#基础的游戏开发学习者,聚焦2D动作游戏核心机制实现与工程化落地。资源包含443个文件,以90个C#脚本(涵盖角色控… · 2026/9/24 18:13:46
C++数据结构继承的概念与菱形继承及虚拟继承和组合 继承:继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到… · 2026/9/24 18:13:46
YOLOv8农田虫情测报灯害虫识别系统:从数据训练到界面部署 简介:基于YOLOv8的农田智能虫情测报灯害虫种类识别系统,是一套面向计算机视觉与深度学习方向毕业设计或课程设计的完整项目,以农田害虫识别为场景,包含训练好的模型权重、可视化界面、完整数据集和部署教程,代码测试运… · 2026/9/24 18:13:39
LSTM财务因子选股:从数据清洗到回测的完整指南 简介:这是一份面向毕业设计场景的LSTM财务因子预测选股模型Python源码,适合金融科技、人工智能及相关专业学生用于课程设计或毕业设计。项目基于历史财务因子与行情数据,通过LSTM神经网络构建预测模型,并附带MindGo平台接口脚本、… · 2026/9/24 18:13:39
基于Servlet+JSP+MySQL的学生成绩管理系统:从架构到避坑全解析 简介:这是一套基于ServletJspMySQL实现的学生成绩管理系统项目,完整附带源码与数据库脚本,面向计算机相关专业正在做毕业设计的学生,也适合需要Java Web项目实战训练的初中级学习者,可协助解决项目代码、数据库设计及部… · 2026/9/24 18:13:39
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程 简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13
1D-CNN时间序列建模实战:从Conv1d原理到工业落地 简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26
柔软的L:汉语语流中被忽视的舌肌张力控制 1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44