Flutter URDF解析插件urdf_parser的使用

发布于 1周前 作者 yibo5220 来自 Flutter

Flutter URDF解析插件urdf_parser的使用

此库主要是一个基于 Dart 的扩展版本,它是从 gkjohnson/urdf-loaders 扩展而来,用于在 wasabia/three_dart 的 Dart 版本中。

它包括一个 STL + DAE 加载器、URDF 解析器和四元数 + Vector3 扩展类。

该库适用于所有当前支持的 three_dart 平台,目前包括 iOS、Android、macOS 和 Windows。

基本用法

需要一个正在运行的 three_dart 项目。

在您的 initPage() 函数中加载您的 dae/stl 文件或 URDF 模型。

void initPage() async {
    scene = three.Scene();
    // ...

    // --- STL ---
    three.Object3D stlObject = await STLLoader(null).loadAsync("path to stl file");
    scene.add(stlObject);

    // --- DAE ---
    List<three.Object3D> daeObjects = await DAELoader.loadFromPath('path to dae file', []);
    for (three.Object3D object in daeObjects) {
        scene.add(object);
    }

    // --- URDF ---
    // 解析 URDF 文件到 URDFRobot 对象
    URDFRobot? robot = await URDFLoader.parse(
        "path to urdf file",
        "path to urdf content folder where stl/dae files are located",
    );

    // 创建一个 three_dart 递归对象并将其添加到场景中
    scene.add(robot.getObject());
}

移动关节

在 URDF 文件中定义的关节可以通过 trySetAngle() 方法移动。

robot.trySetAngle("angleName", amount);

基本示例:按顺序动画化所有可用关节

void render() {
    // ...

    double time = DateTime.now().millisecondsSinceEpoch / 6e4;

    List<MapEntry<String, URDFJoint>> joints = (robot!.joints.entries.where(
        (entry) => entry.value.type != "fixed")).toList();

    // 机器人关节测试动画
    double periodicValueSmall = sin((time * joints.length) % 1 * 2 * pi) / 2 + 0.5;
    int s = (time * joints.length).floor() % joints.length;

    // 设置最后一个角度旋转为 0.5
    int lastS = (s - 1 + joints.length) % joints.length;
    robot!.trySetAngle(
        joints[lastS].key, 
        lerpDouble(joints[lastS].value.lower, joints[lastS].value.upper, 0.5)!,
    );

    robot!.trySetAngle(
        joints[s].key, 
        lerpDouble(joints[s].value.lower, joints[s].value.upper, periodicValueSmall)!,
    );

    // ...
}

支持的关节类型

  • fixed
  • continuous
  • revolute
  • prismatic
  • mimic

支持的 3D 文件类型

  • .stl/.STL(二进制和 ASCII 变体)
  • .dae

其他功能

  • 支持从二进制/ASCII STL 文件、DAE 文件和基本 URDF 颜色节点中提取颜色。
  • 支持解析 DAE 文件中的线条数据。

颜色格式

除了明显的 DAE 文件定义材料外,STL 文件也可以包含颜色信息。但是,不幸的是,这没有官方标准。

该库支持以下 STL 颜色格式:

ASCII STL 颜色格式
solid object1
  facet normal 0.0 0.0 0.0
    outer loop
      vertex 1.0 0.0 0.0
      vertex 0.0 1.0 0.0
      vertex 0.0 0.0 1.0
    endloop
  endfacet
endsolid object1=RGB(0,0,255)

solid object2
  facet normal 0.0 0.0 0.0
    outer loop
      vertex -1.0 0.0 0.0
      vertex 0.0 -1.0 0.0
      vertex 0.0 0.0 -1.0
    endloop
  endfacet
endsolid object2=RGB(255,0,0)

更多关于Flutter URDF解析插件urdf_parser的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter URDF解析插件urdf_parser的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中解析URDF(Unified Robot Description Format)文件通常需要借助一些底层的Dart库或者通过调用原生平台(如Android或iOS)的代码来实现。由于Flutter本身并没有直接支持URDF解析的官方插件,我们通常会寻找社区提供的第三方插件或者自己实现一个插件。

假设你找到了一个名为urdf_parser的Flutter插件(请注意,这个插件可能并不存在,或者不是官方或广泛认可的插件,这里只是为了说明如何使用),你可以按照以下步骤来集成和使用它。以下是一个假设性的代码案例,用于展示如何在Flutter项目中解析URDF文件。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加urdf_parser插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  urdf_parser: ^x.y.z  # 替换为实际的版本号

然后运行flutter pub get来安装依赖。

2. 导入插件并解析URDF

在你的Dart文件中导入插件并解析URDF文件。这里假设urdf_parser插件提供了一个parseUrdf方法来解析URDF字符串或文件内容。

import 'package:flutter/material.dart';
import 'package:urdf_parser/urdf_parser.dart';  // 假设的导入路径

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String urdfContent = """
  <robot name="test_robot">
    <link name="base_link">
      <inertial>
        <mass value="1.0"/>
        <inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>
      </inertial>
      <visual>
        <geometry>
          <box size="0.1 0.1 0.1"/>
        </geometry>
      </visual>
    </link>
    <!-- 更多URDF内容 -->
  </robot>
  """;

  UrdfRobot? robot;

  @override
  void initState() {
    super.initState();
    _parseUrdf();
  }

  Future<void> _parseUrdf() async {
    try {
      // 假设parseUrdf方法接受一个URDF字符串并返回一个UrdfRobot对象
      robot = await UrdfParser.parseUrdf(urdfContent);
      print('URDF parsed successfully!');
      // 可以在这里处理解析后的数据,例如更新UI
    } catch (e) {
      print('Error parsing URDF: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('URDF Parser Demo'),
        ),
        body: Center(
          child: robot != null
              ? Text('URDF parsed successfully!')
              : CircularProgressIndicator(),
        ),
      ),
    );
  }
}

3. 假设的UrdfParser

由于urdf_parser插件可能并不真实存在,这里提供一个假设的UrdfParser类的定义,用于说明可能的API设计。在实际使用中,你需要根据真实插件的API来调整代码。

class UrdfParser {
  // 假设的静态方法,用于解析URDF字符串
  static Future<UrdfRobot> parseUrdf(String urdfString) async {
    // 这里应该是实际的解析逻辑,可能是调用原生代码或第三方库
    // 由于这是假设的,我们直接返回一个模拟的UrdfRobot对象
    return UrdfRobot(name: 'Parsed Robot');
  }
}

class UrdfRobot {
  final String name;

  UrdfRobot({required this.name});

  // 其他属性和方法...
}

注意

  • 上述代码是基于假设的插件和API设计的,实际使用时需要根据真实插件的文档和API来调整。
  • 如果urdf_parser插件不存在,你可能需要自己实现一个Flutter插件,通过调用C++、Python等语言的URDF解析库来完成解析工作,或者使用现有的原生库并通过Flutter的Platform Channels进行通信。
  • 解析URDF文件通常涉及复杂的机器人学知识,确保你理解URDF文件的格式和解析后的数据结构。
回到顶部