Flutter网络或IP服务插件epitaph_ips的使用

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

Flutter网络或IP服务插件epitaph_ips的使用

关于该项目

Epitaph IPS 是一个用Dart语言编写的库,用于计算用户在设备上的位置。项目主要用于在用户设备上计算位置。该库使用了Flutter框架,并利用蓝牙低功耗(BLE)信标进行计算。接收信号强度指示(RSSI)值用于计算用户在真实世界中的位置。

(返回顶部)

构建工具

该库使用以下工具构建:

(返回顶部)

安装

安装方法将在后续版本中更新。

(返回顶部)

使用

跟踪

跟踪系统由多个模块组成,这些模块理论上可以单独使用。

模块描述

  • 计算器 - 通过读取值(例如来自BLE信标的RSSI值)来计算原始位置的模块。
  • 过滤器 - 平滑处理原始位置的模块。当值比较嘈杂时,这非常有用。
  • 追踪器 - 使用计算器和过滤器连续跟踪用户位置的模块。
  • 映射器 - 继承自追踪器,用于在地图上跟踪用户位置(包括相关的图、节点和边)。

计算器(抽象)

  • 包含 Point calculate(List<Beacon>)
  • 从列表中读取某些值并使用这些值计算位置。
  • Epitaph IPS 提供了一个实现的(非线性三边定位)计算器,它使用简单的Levenberg-Marquardt算法。

过滤器(抽象)

  • 包含 Point filter(Point), void configFilter(Point), void reset()
  • 实现的过滤器应持续接收一个点,对其进行处理并保存结果以供后续处理。
  • Epitaph IPS 提供了一个实现的过滤器,形式为简单的无迹卡尔曼滤波器。

追踪器

  • 首先使用计算器计算一个原始位置,然后使用过滤器处理结果。
  • 结果位置可以根据需要进一步处理。
  • 尽管追踪器包含多个方法,但 void initiateTrackingCycle(List<Beacon>) 包含所有相关的方法。

映射器

  • 继承自追踪器。
  • 除了追踪器的功能外,映射器还会在计算和过滤后尝试更深入地理解位置与地图的关系。
  • 包含许多额外的方法,最重要的方法是重载的 void initiateTrackingCycle(List<Beacon>)

示例代码

import 'package:epitaph_ips/calculator.dart';
import 'package:epitaph_ips/filter.dart';
import 'package:epitaph_ips/tracker.dart';
import 'package:epitaph_ips/mapper.dart';

// 初始化计算器
Calculator calculator = LMA();

// 非常基本的模型用于无迹卡尔曼滤波器
Matrix fxUserLocation(Matrix x, double dt, List? args) {
  List<double> list = [
    x[1][0] * dt + x[0][0],
    x[1][0],
    x[3][0] * dt + x[2][0],
    x[3][0]
  ];
  return Matrix.fromFlattenedList(list, 4, 1);
}

Matrix hxUserLocation(Matrix x, List? args) {
  return Matrix.row([x[0][0], x[0][2]]);
}

// 无迹卡尔曼滤波器的Sigma点函数
SigmaPointFunction sigmaPoints = MerweFunction(4, 0.1, 2.0, 1.0);

// 初始化过滤器
Filter filter = SimpleUKF(4, 2, 0.3, hxUserLocation, fxUserLocation, sigmaPoints, sigmaPoints.numberOfSigmaPoints());

// 初始化追踪器
Tracker tracker = Tracker(calculator, filter);

// 通过调用此方法并传递至少三个Beacon实例来启动追踪
tracker.initiateTrackingCycle(...);

// 可以获取追踪器的结果
tracker.finalPosition;

// 可以获取原始计算位置和过滤后的位置
tracker.calculatedPosition;
tracker.filteredPosition;

// 过滤器可以独立于追踪器使用;提供Point实例给过滤方法
filter.filter(...);

// 计算器可以独立于追踪器使用;提供一个包含至少三个Beacon实例的列表
calculator.calculate(...);

文档

文档将在后续版本中更新。

(返回顶部)

贡献

贡献使开源社区成为一个学习、启发和创造的绝佳场所。任何贡献都将被高度赞赏。

如果您有任何改进的建议,请创建一个带有“增强”标签的问题,然后分叉仓库并创建一个拉取请求。也可以直接打开一个带有“增强”标签的问题。 别忘了给项目点赞!再次感谢!

  1. 创建一个带有“增强”标签的问题。
  2. 分叉项目。
  3. 创建您的功能分支 (git checkout -b feature/AmazingFeature)
  4. 提交您的更改 (git commit -m '添加一些AmazingFeature')
  5. 推送到分支 (git push origin feature/AmazingFeature)
  6. 打开一个拉取请求

更多关于如何设置所需环境的信息请参阅 Flutter Team的指南

我们还建议查看 Flutter Team的风格指南

更多关于此信息请参阅 CODE_OF_CONDUCT文件

(返回顶部)

路线图

有关提议功能、已知问题和最新路线图的完整列表,请参阅 开放问题

(返回顶部)

许可证

该项目根据MIT许可证分发。更多信息请参阅 LICENSE 文件。

(返回顶部)

联系方式

(返回顶部)

示例代码

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // 这个小部件是你的应用的根。
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // 这是你的应用的主题。
        //
        // 尝试运行你的应用,你会看到应用有一个蓝色的工具栏。然后,在不退出应用的情况下,将primarySwatch改为Colors.green,并重新加载应用。
        // 注意计数器并没有重置到零;应用并没有重启。
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  // 这个小部件是你的应用的主页。它是有状态的,意味着它有一个状态对象(定义在下面),该状态对象包含影响其外观的字段。
  // 这个类是状态的配置。它持有由父级(在这个例子中是App小部件)提供的值(在这个例子中是标题),并在构建方法中使用这些值。小部件子类中的字段总是标记为“final”。

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      // 这次调用setState告诉Flutter框架有些东西改变了,因此会重新运行下面的构建方法,以便显示更新后的值。如果我们不调用setState()而改变_counter,则不会重新运行构建方法,因此看起来什么都没有发生。
      _counter++;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    // 每次调用setState都会重新运行这个方法,就像上面的_incrementCounter方法一样。
    //
    // Flutter框架已经被优化为快速重新运行构建方法,因此你可以重建任何需要更新的东西,而不是逐个更改小部件实例。
    return Scaffold(
      appBar: AppBar(
        // 这里我们从MyHomePage对象中获取值,该对象是由App.build方法创建的,并使用它来设置我们的appbar标题。
        title: Text(widget.title),
      ),
      body: Center(
        // Center是一个布局小部件。它接受一个子元素并将其放在父元素的中间。
        child: Column(
          // Column也是一个布局小部件。它接受一个小部件列表并垂直排列它们。默认情况下,它水平调整自己的大小以适应其子元素,并尽可能高。
          //
          // 调试绘制(在控制台按“p”,选择Android Studio中的“切换调试绘制”操作,或者Visual Studio Code中的“切换调试绘制”命令)可以看到每个小部件的线框。
          //
          // Column有各种属性来控制它的大小和如何定位其子元素。这里我们使用mainAxisAlignment来垂直居中子元素;主轴是垂直的,因为Columns是垂直的(交叉轴是水平的)。
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              '你已经按下按钮这么多次:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: '增加',
        child: const Icon(Icons.add),
      ), // 这个尾随逗号使得自动格式化更好看。
    );
  }
}

更多关于Flutter网络或IP服务插件epitaph_ips的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter网络或IP服务插件epitaph_ips的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用epitaph_ips插件来获取网络或IP服务的一个简单示例。这个插件的具体功能和使用方法可能会根据插件的最新版本有所变化,因此请参考官方文档以获取最新信息。不过,以下代码提供了一个基本的框架,展示了如何集成和使用该插件。

首先,确保你已经在pubspec.yaml文件中添加了epitaph_ips依赖:

dependencies:
  flutter:
    sdk: flutter
  epitaph_ips: ^最新版本号  # 替换为插件的最新版本号

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

接下来,在你的Flutter应用中,你可以按照以下步骤使用epitaph_ips插件:

  1. 导入插件

在你的Dart文件中导入插件:

import 'package:epitaph_ips/epitaph_ips.dart';
  1. 初始化并使用插件

下面是一个简单的示例,展示了如何使用epitaph_ips插件来获取IP服务信息:

import 'package:flutter/material.dart';
import 'package:epitaph_ips/epitaph_ips.dart';

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

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

class _MyAppState extends State<MyApp> {
  String? ipInfo;

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

  Future<void> _getIpInfo() async {
    try {
      // 假设插件提供了一个名为getIpInfo的方法,具体方法名请参考插件文档
      var info = await EpitaphIps.getIpInfo();
      setState(() {
        ipInfo = info.toString(); // 根据返回的数据类型调整这里
      });
    } catch (e) {
      setState(() {
        ipInfo = 'Error: ${e.message}';
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Epitaph IPs Example'),
        ),
        body: Center(
          child: Text(ipInfo ?? 'Loading IP Info...'),
        ),
      ),
    );
  }
}

注意

  • 上面的代码假设EpitaphIps类有一个名为getIpInfo的静态方法,该方法返回一个Future对象。实际上,你需要参考epitaph_ips插件的官方文档来了解其具体的API和调用方法。
  • 如果插件返回的是一个复杂的数据结构(如JSON对象),你可能需要解析这个数据结构来提取你需要的信息。
  • 错误处理是非常重要的,尤其是在进行网络请求时。上面的代码展示了如何捕获并处理异常。

由于epitaph_ips插件的具体实现细节可能有所不同,上述代码仅提供了一个基本框架。在实际使用时,请务必参考插件的官方文档和示例代码。

回到顶部