鸿蒙UIAbility组件概述(一)

OpenHarmony实战开发-组件复用实践。 若开发者的应用中存在以下场景,并成为UI线程的帧率瓶颈,应该考虑使用组件复用机制提升应用性能: 阅读详情

概述

UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口。一个应用可以包含一个或者多个UIAbility组件。

每一个UIAbility组件都会在最近任务列表中显示一个对应的任务。

声明配置

需要再module.json5文件的abilites标签中声明UIAbility的名称、入口、标签等相关信息。

{
  "module": {
    ...
    "abilities": [
      {
        "name": "EntryAbility", // UIAbility组件的名称
        "srcEntry": "./ets/entryability/EntryAbility.ets", // UIAbility组件的代码路径
        "description": "$string:EntryAbility_desc", // UIAbility组件的描述信息
        "icon": "$media:icon", // UIAbility组件的图标
        "label": "$string:EntryAbility_label", // UIAbility组件的标签
        "startWindowIcon": "$media:icon", // UIAbility组件启动页面图标资源文件的索引
        "startWindowBackground": "$color:start_window_background", // UIAbility组件启动页面背景颜色资源文件的索引
        ...
      }
    ]
  }
}

UIAbility组件声明周期

UIAbility生命周期状态图
在这里插入图片描述

生命周期状态说明

Create状态

Create状态为应用加载过程中,UIAbility实例创建完成时触发,系统会回调onCreate()方法,可以在该方法中进行页面的初始化操作,如资源加载等。

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    // 页面初始化
  }
  // ...
}

Want是对象间信息传递的载体,可以用于应用组件间的信息传递。

WindowStageCreate和WindowStageDestroy状态

在这里插入图片描述

UIAbility实例创建完成之后,进入Foreground之前,系统会创建一个WindowStage。WindowStage创建完成后会调用onWindowStageCreate()方法,可以在该回调中进行UI加载、设置WindowStage事件订阅等。

在onWindowStageCreate()中通过loadContent()方法设置应用要加载的页面,并根据需要调用on('windowStageEvent')方法订阅WindowStage事件(获取焦点、失去焦点、可见、不可见)。

import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import { hilog } from '@kit.PerformanceAnalysisKit';

const TAG: string = '[EntryAbility]';
const DOMAIN_NUMBER: number = 0xFF00;

export default class EntryAbility extends UIAbility {
  // ...
  onWindowStageCreate(windowStage: window.WindowStage): void {
    // 设置WindowStage的事件订阅(获焦/失焦、可见/不可见)
    try {
      windowStage.on('windowStageEvent', (data) => {
        let stageEventType: window.WindowStageEventType = data;
        switch (stageEventType) {
          case window.WindowStageEventType.SHOWN: // 切到前台
            hilog.info(DOMAIN_NUMBER, TAG, 'windowStage foreground.');
            break;
          case window.WindowStageEventType.ACTIVE: // 获焦状态
            hilog.info(DOMAIN_NUMBER, TAG, 'windowStage active.');
            break;
          case window.WindowStageEventType.INACTIVE: // 失焦状态
            hilog.info(DOMAIN_NUMBER, TAG, 'windowStage inactive.');
            break;
          case window.WindowStageEventType.HIDDEN: // 切到后台
            hilog.info(DOMAIN_NUMBER, TAG, 'windowStage background.');
            break;
          default:
            break;
        }
      });
    } catch (exception) {
      hilog.error(DOMAIN_NUMBER, TAG, 'Failed to enable the listener for window stage event changes. Cause:' + JSON.stringify(exception));
    }
    hilog.info(DOMAIN_NUMBER, TAG, '%{public}s', 'Ability onWindowStageCreate');
    // 设置UI加载
    windowStage.loadContent('pages/Index', (err, data) => {
      // ...
    });
  }
}

对应onWindowStageCreage()回调的是,在UIAbility实例销毁之前,系统会回调onWindowStageDestroy()回调,可以在该回调中释放UI资源。

import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';

const TAG: string = '[EntryAbility]';
const DOMAIN_NUMBER: number = 0xFF00;

export default class EntryAbility extends UIAbility {
  windowStage: window.WindowStage | undefined = undefined;

  // ...
  onWindowStageCreate(windowStage: window.WindowStage): void {
    this.windowStage = windowStage;
    // ...
  }

  onWindowStageDestroy() {
    // 释放UI资源
    // 例如在onWindowStageDestroy()中注销获焦/失焦等WindowStage事件
    try {
      if (this.windowStage) {
        this.windowStage.off('windowStageEvent');
      }
    } catch (err) {
      let code = (err as BusinessError).code;
      let message = (err as BusinessError).message;
      hilog.error(DOMAIN_NUMBER, TAG, `Failed to disable the listener for windowStageEvent. Code is ${code}, message is ${message}`);
    }
  }
}

WindowStageWillDestroy状态

对应onWindowStageWillDestroy()回调,在WindowStage销毁前执行,此时WindowStage可以使用。

import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  windowStage: window.WindowStage | undefined = undefined;
  // ...
  onWindowStageCreate(windowStage: window.WindowStage): void {
    this.windowStage = windowStage;
    // ...
  }
  onWindowStageWillDestroy(windowStage: window.WindowStage) {
    // 释放通过windowStage对象获取的资源
  }
  onWindowStageDestroy() {
    // 释放UI资源
  }
}

Foreground和Background状态

Foreground和Background状态分别在UIAbility实例切换至前台和切换至后台时触发,对应于onForeground()回调和onBackground()回调。

onForeground()回调,在UIAbility的UI可见之前,如UIAbility切换至前台时触发。可以在onForeground()回调中申请系统需要的资源,或者重新申请在onBackground()中释放的资源。

onBackground()回调,在UIAbility的UI完全不可见之后,如UIAbility切换至后台时候触发。可以在onBackground()回调中释放UI不可见时无用的资源,或者在此回调中执行较为耗时的操作,例如状态保存等。

import { UIAbility } from '@kit.AbilityKit';

export default class EntryAbility extends UIAbility {
  // ...

  onForeground(): void {
    // 申请系统需要的资源,或者重新申请在onBackground()中释放的资源
  }

  onBackground(): void {
    // 释放UI不可见时无用的资源,或者在此回调中执行较为耗时的操作
    // 例如状态保存等
  }
}

当应用的UIAbility实例已经创建,且UIAbility配置为singleton启动模式时,再次调用startAbility()方法启动该UIAbility实例时,只会进入该UIAbility的onNewWant()回调,不会进入onCreate()回调和onWindowStageCreate()回调。可以根据新传入的Want来更新要加载的资源和数据等。

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';

export default class EntryAbility extends UIAbility {
  // ...

  onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam) {
    // 更新资源、数据
  }
}

Destroy状态

Destroy状态是UIAbility实例销毁时触发。可以在onDestroy回调中进行系统资源的释放、数据的保存等操作。

例如调用terminateSelf()方法停止当前UIAbility实例,从而完成UIAbility实例的销毁;或者用户使用最近任务列表关闭该UIAbility实例,完成UIAbility的销毁。

import { UIAbility } from '@kit.AbilityKit';

export default class EntryAbility extends UIAbility {
  // ...

  onDestroy() {
    // 系统资源的释放、数据的保存等
  }
}

UIAbility组件启动模式

singleton 单实例模式

singleton启动模式为单实例模式,也是默认的启动模式。

每次调用startAbility()方法时,如果应用进程中该类型的UIAbility实例已经存在,则复用系统中的UIAbility实例。系统中只存在唯一一个该UIAbility实例,即在最近任务列表中只存在一个该类型的UIAbility实例。

请添加图片描述
如果需要使用singleton启动模式,在module.json5配置文件中的launchType字段配置为singleton即可。

{
  "module": {
    ...
    "abilities": [
      {
        "launchType": "singleton",
        ...
      }
    ]
  }
}

multiton 多实例模式

multiton启动模式为多实例模式,每次调用startAbility()方法时,都会在应用进程中创建一个新的该类型UIAbility实例。即在最近任务列表中可以看到有多个该类型的UIAbility实例。这种情况下可以将UIAbility配置为multiton(多实例模式)。

请添加图片描述
multiton启动模式的开发使用,在module.json5配置文件中的launchType字段配置为multiton即可。

{
  "module": {
    ...
    "abilities": [
      {
        "launchType": "multiton",
        ...
      }
    ]
  }
}

specified 指定实例模式

specified启动模式为指定实例模式,针对一些特殊场景使用(例如文档应用中每次新建文档希望都能新建一个文档实例,重复打开一个已保存的文档希望打开的都是同一个文档实例)。请添加图片描述
例如有两个UIAbility:EntryAbility和SpecifiedAbility,SpecifiedAbility配置为指定实例模式启动,需要从EntryAbility的页面中启动SpecifiedAbility。

  1. 在SpecifiedAbility中,将module.json5配置文件的launchType字段配置为specified。

    {
      "module": {
        ...
        "abilities": [
          {
            "launchType": "specified",
            ...
          }
        ]
      }
    }
    
  2. 在创建UIAbility实例之前,开发者可以为该实例指定一个唯一的字符串Key,这样在调用startAbility()方法时,应用就可以根据指定的Key来识别响应请求的UIAbility实例。在EntryAbility中,调用startAbility()方法时,可以在want参数中增加一个自定义参数,例如instanceKey,以此来区分不同的UIAbility实例。

     // 在启动指定实例模式的UIAbility时,给每一个UIAbility实例配置一个独立的Key标识
     // 例如在文档使用场景中,可以用文档路径作为Key标识
     import { common, Want } from '@kit.AbilityKit';
     import { hilog } from '@kit.PerformanceAnalysisKit';
     import { BusinessError } from '@kit.BasicServicesKit';
    
     const TAG: string = '[Page_StartModel]';
     const DOMAIN_NUMBER: number = 0xFF00;
    
     function getInstance(): string {
       return 'KEY';
     }
    
     @Entry
     @Component
     struct Page_StartModel {
       private KEY_NEW = 'KEY';
    
       build() {
         Row() {
           Column() {
             // ...
             Button()// ...
               .onClick(() => {
                 let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
                 // context为调用方UIAbility的UIAbilityContext;
                 let want: Want = {
                   deviceId: '', // deviceId为空表示本设备
                   bundleName: 'com.samples.stagemodelabilitydevelop',
                   abilityName: 'SpecifiedFirstAbility',
                   moduleName: 'entry', // moduleName非必选
                   parameters: {
                     // 自定义信息
                     instanceKey: this.KEY_NEW
                   }
                 };
                 context.startAbility(want).then(() => {
                   hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in starting SpecifiedAbility.');
                 }).catch((err: BusinessError) => {
                   hilog.error(DOMAIN_NUMBER, TAG, `Failed to start SpecifiedAbility. Code is ${err.code}, message is ${err.message}`);
                 })
                 this.KEY_NEW = this.KEY_NEW + 'a';
               })
             // ...
             Button()// ...
               .onClick(() => {
                 let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
                 // context为调用方UIAbility的UIAbilityContext;
                 let want: Want = {
                   deviceId: '', // deviceId为空表示本设备
                   bundleName: 'com.samples.stagemodelabilitydevelop',
                   abilityName: 'SpecifiedSecondAbility',
                   moduleName: 'entry', // moduleName非必选
                   parameters: {
                     // 自定义信息
                     instanceKey: getInstance()
                   }
                 };
                 context.startAbility(want).then(() => {
                   hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in starting SpecifiedAbility.');
                 }).catch((err: BusinessError) => {
                   hilog.error(DOMAIN_NUMBER, TAG, `Failed to start SpecifiedAbility. Code is ${err.code}, message is ${err.message}`);
                 })
                 this.KEY_NEW = this.KEY_NEW + 'a';
               })
             // ...
           }
           .width('100%')
         }
         .height('100%')
       }
     }
    
  3. 由于SpecifiedAbility的启动模式被配置为指定实例启动模式,因此在SpecifiedAbility启动之前,会先进入对应的AbilityStage的onAcceptWant()生命周期回调中,以获取该UIAbility实例的Key值。然后系统会自动匹配,如果存在与该UIAbility实例匹配的Key,则会启动与之绑定的UIAbility实例,并进入该UIAbility实例的onNewWant()回调函数;否则会创建一个新的UIAbility实例,并进入该UIAbility实例的onCreate()回调函数和onWindowStageCreate()回调函数。示例代码中,通过实现onAcceptWant()生命周期回调函数,解析传入的want参数,获取自定义参数instanceKey。业务逻辑会根据这个参数返回一个字符串Key,用于标识当前UIAbility实例。如果返回的Key已经对应一个已启动的UIAbility实例,系统会将该UIAbility实例拉回前台并获焦,而不会创建新的实例。如果返回的Key没有对应已启动的UIAbility实例,则系统会创建新的UIAbility实例并启动。

     import { AbilityStage, Want } from '@kit.AbilityKit';
    
     export default class MyAbilityStage extends AbilityStage {
       onAcceptWant(want: Want): string {
         // 在被调用方的AbilityStage中,针对启动模式为specified的UIAbility返回一个UIAbility实例对应的一个Key值
         // 当前示例指的是module1 Module的SpecifiedAbility
         if (want.abilityName === 'SpecifiedFirstAbility' || want.abilityName === 'SpecifiedSecondAbility') {
           // 返回的字符串Key标识为自定义拼接的字符串内容
           if (want.parameters) {
             return `SpecifiedAbilityInstance_${want.parameters.instanceKey}`;
           }
         }
         // ...
         return 'MyAbilityStage';
       }
     }
    

例如在文档应用中,可以为不同的文档实例内容绑定不同的Key值。每次新建文档时,可以传入一个新的Key值(例如可以将文件的路径作为一个Key标识),此时AbilityStage中启动UIAbility时都会创建一个新的UIAbility实例;当新建的文档保存之后,回到桌面,或者新打开一个已保存的文档,回到桌面,此时再次打开该已保存的文档,此时AbilityStage中再次启动该UIAbility时,打开的仍然是之前原来已保存的文档界面。

以如下步骤所示进行举例说明。

  1. 打开文件A,对应启动一个新的UIAbility实例,例如启动UIAbility实例1。
  2. 在最近任务列表中关闭文件A的任务进程,此时UIAbility实例1被销毁,回到桌面,再次打开文件A,此时对应启动一个新的UIAbility实例,例如启动UIAbility实例2。
  3. 回到桌面,打开文件B,此时对应启动一个新的UIAbility实例,例如启动UIAbility实例3。
  4. 回到桌面,再次打开文件A,此时仍然启动之前的UIAbility实例2,因为系统会自动匹配UIAbility实例的Key值,如果存在与之匹配的Key,则会启动与之绑定的UIAbility实例。在此例中,之前启动的UIAbility实例2与文件A绑定的Key是相同的,因此系统会拉回UIAbility实例2并让其获焦,而不会创建新的实例。
【最新鸿蒙应用开发】——一篇搞懂什么是UIAbility UIAbility组件是一种包含UI的应用组件,UIAbility组件是系统调度的基本单元(最小单元),为应用提供绘制界面的窗口,。一个应用可以包含一个或多个UIAbility组件。UIAbility划分原则与建议:UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口。一个应用可以包含一个或多个UIAbility组件。例如,在支付应用中,可以将入口功能和收付款功能分别配置为独立的UIAbility。每一个UIAbility组件实例都会在最近任务列表中显示一个对应的任务。 阅读详情

相关推荐

鸿蒙开发-应用程序框架UIAbility的使用

UIAbility是一种包含用户界面的应用组件,主要用于和用户进行交互。UIAbility也是系统调度的单元,为应用提供窗口在其中绘制界面。每一个UIAbility实例,都对应于一个最近任务列表中的任务。一个应用可以有一个UIAbility,也可以有多个UIAbility,如下图所示。例如浏览器应用可以通过一个UIAbility结合多页面的形式让用户进行的搜索和浏览内容;

m0_62167422的博客 1744

【鸿蒙软件开发】UIAbility组件概况、生命周期与启动模式

UIAbility组件是一种包含UI界面的应用组件,主要用于和用户交互。UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口;一个UIAbility组件中可以通过多个页面来实现一个功能模块。每一个UIAbility组件实例,都对应于一个最近任务列表中的任务。UIAbility组件是一种包含UI界面的应用组件,主要用于和用户交互。UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口;一个UIAbility组件中可以通过多个页面来实现一个功能模块。

m0_62599305的博客 6697

鸿蒙5.0开发:Stage模型(UIAbility组件)

UIAbility是HarmonyOS系统中用于构建用户界面的基本组件之一。

AyomQAQ的博客 2311

HarmonyOS实战开发:UIAbility组件

UIAbility组件是一种包含UI的应用组件,主要用于和用户交互......

2401_84194030的博客 1034

【鸿蒙 HarmonyOS】必备——UIAbility组件生命周期

UIAbility组件是一种包含UI的应用组件,主要用于和用户交互。UIAbility的设计理念:原生支持应用组件级的跨端迁移和多端协同。支持多设备和多窗口形态。UIAbility划分原则与建议:UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口。一个应用可以包含一个或多个UIAbility组件。例如,在支付应用中,可以将入口功能和收付款功能分别配置为独立的UIAbility。每一个UIAbility组件实例都会在最近任务列表中显示一个对应的任务。

weixin_50589123的博客 1239

鸿蒙开发基础——启动应用内的UIAbility组件

一个 UIAbility 可以对应多个页面,在不同的场景下启动该UIAbility时需要展示不同的页面,例如从一个UIAbility的页面中跳转到另外一个UIAbility时,希望启动目标UIAbility的指定页面。UIAbility的启动分为两种情况:UIAbility冷启动和UIAbility热启动。UIAbility冷启动:指的是UIAbility实例处于完全关闭状态下被启动,这需要完整地加载和初始化UIAbility实例的代码、资源等。

guangxishaoji的博客 1061

HarmonyOS:UIAbility组件间交互(设备内)

启动应用内的UIAbility并获取返回结果 在一个EntryAbility启动另外一个FuncAbility时,希望在被启动的FuncAbility完成相关业务后,能将结果返回给调用方。

ChinaDragon10的博客 1734

HarmonyOS 应用开发之UIAbility组件间交互(设备内)

一个UIAbility可以对应多个页面,在不同的场景下启动该UIAbility时需要展示不同的页面,例如从一个UIAbility的页面中跳转到另外一个UIAbility时,希望启动目标UIAbility的指定页面。UIAbility的启动分为两种情况:UIAbility冷启动和UIAbility热启动。UIAbility冷启动:指的是UIAbility实例处于完全关闭状态下被启动,这需要完整地加载和初始化UIAbility实例的代码、资源等。

maniuT的博客 3030

华为鸿蒙 UIAbility 组件:构建用户界面的舞台

UIAbility是华为鸿蒙系统中用于构建用户界面的应用组件,它负责创建和管理界面元素,响应用户操作,并与用户进行交互。UIAbility 组件可以包含一个或多个页面,每个页面都可以独立加载和卸载,方便地进行界面管理和功能扩展。UIAbility 组件的主要功能界面渲染:UIAbility 组件可以使用 ArkUI 库提供的各种组件构建用户界面,例如按钮、文本、图片、列表等。事件处理:UIAbility 组件可以监听和处理各种用户事件,例如点击、触摸、滑动等。数据绑定。

same4869的博客 961

HarmonyOS Next开发学习手册——UIAbility组件启动模式

UIAbility的启动模式是指UIAbility实例在启动时的不同呈现状态。

maniuT的博客 1742

鸿蒙HarmonyOS实战-UIAbility页面跳转_鸿蒙os开发uiabillty之间的跳转

android.settings.INPUT_METHOD_SUBTYPE_SETTINGS 【API 11及以上】 // 跳转 语言选择界面 【多国语言选择】android.settings.NFC_SETTINGS 显示NFC设置。android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS 跳转到应用程序界面【所有的】android.settings.INTERNAL_STORAGE_SETTINGS 跳转存储设置界面【内部存储】

2401_84181108的博客 1364

鸿蒙UIAbility组件概述(二)

例如在应用中将入口功能和帐号登录功能分别设计为两个独立的UIAbility,在帐号登录UIAbility中完成登录操作后,需要将登录的结果返回给入口UIAbility。应用中的UIAbility在启动过程中,需要指定启动页面,否则应用启动后会因为没有默认加载页面而导致白屏。一个UIAbility可以对应多个页面,在不同的场景下启动该UIAbility时需要展示不同的页面,例如从一个UIAbility的页面中跳转到另外一个UIAbility时,希望启动目标UIAbility的指定页面。

gitzzp的博客 1550

HarmonyOS Next开发学习手册——UIAbility组件基本用法

UIAbility组件的基本用法包括:指定UIAbility的启动页面以及获取UIAbility的上下文 UIAbilityContext。

maniuT的博客 1265

鸿蒙:UIAbility、页面及组件的生命周期

①自定义组件:@Component装饰的UI单元,可以组合多个系统组件实现UI的复用,可以调用组件的生命周期。②页面:即应用的UI页面。可以由一个或者多个自定义组件组成,@Entry装饰的自定义组件为页面的入口组件,即页面的根节点,一个页面有且仅能有一个@Entry。只有被@Entry装饰的组件才可以调用页面的生命周期。

weixin_71403100的博客 5849

【鸿蒙开发】学习笔录——UIAbility组件生命周期

UIAbility组件是一种包含UI的应用组件,主要用于和用户交互。UIAbility的设计理念:原生支持应用组件级的跨端迁移和多端协同。支持多设备和多窗口形态。UIAbility划分原则与建议:UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口。一个应用可以包含一个或多个UIAbility组件。例如,在支付应用中,可以将入口功能和收付款功能分别配置为独立的UIAbility。每一个UIAbility组件实例都会在最近任务列表中显示一个对应的任务。

2401_88547687的博客 1055

鸿蒙应用程序入口UIAbility详解

UIAbility是一种包含用户界面的应用组件,主要用于和用户进行交互。UIAbility也是系统调度的单元,为应用提供窗口在其中绘制界面。每一个UIAbility实例,都对应于一个最近任务列表中的任务。一个应用可以有一个UIAbility,也可以有多个UIAbility,如下图所示。例如浏览器应用可以通过一个UIAbility结合多页面的形式让用户进行的搜索和浏览内容;

xiangzhihong8的专栏 2414

【鸿蒙学习】深入了解UIAbility组件

UIAbility是HarmonyOS应用开发中的一个重要组件,用于处理用户界面交互。它类似于Android中的Activity和iOS中的ViewController。UIAbility提供了丰富的UI控件,开发者可以通过这些控件构建出美观、易用的应用界面。UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口。一个应用可以包含一个或多个UIAbility组件。例如,在支付应用中,可以将入口功能和收付款功能分别配置为独立的UIAbility。

一个不断前行的程序者 1730

MuJoCo 机械臂关节空间阻抗控制Impedance实现(附代码)

阻抗控制通过调整关节的刚度和阻尼,让机器人在接触时产生顺应性,减少冲击力,其核心目标是在接触外部载荷时能够自适应调整输出力矩,实现力与位置的协同控制。阻抗控制可以很快的到达设定位置,在此基础上,使用mujoco交互中的施加外力操作,可以看到当外力松开后,机械臂也可以很快的回弹回设定位置。其中self.Kp和self.Kd为固定刚度和阻尼系数,通过修改刚度和阻尼参数,可以变得更柔顺来应对各种场景。注释掉该行后,直接simulate仿真可以看到机械臂控制位置震荡等情况,接下来引入关节空间阻抗控制的代码。

darcsdn 1274
上一篇: 鸿蒙应用程序框架基础
下一篇: 鸿蒙UIAbility组件概述(二)
gitzzp
博客等级 码龄11年 307粉丝 60原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值