触觉假肢手的多功能共享控制策略,助力断肢患者实现“一次多抓”及“柔性物体操作-挤牙膏”等任务

假肢手的肌电共享控制策略能让截肢者在更少疲劳的情况下实现更精确的控制,有助于提高肌电假肢手的接受度。随着触觉感知技术的发展,基于触觉感知的肌电共享控制策略引起了研究者的广泛关注。触觉感知技术赋予了假肢手控制系统检测接触、预防滑移和调节抓握力等功能,成功地帮助人类用户完成包括倒水、喝水、抓放物体等一系列的日常生活任务。然而,对于利用先进的机器人技术为假肢手引入何种功能,目前仍存在不同意见。针对上述问题,北京邮电大学方斌教授联合南丹麦大学方承教授共同提出了一种基于触觉感知的多功能共享控制策略。该共享控制策略通过多阶段抓取功能辅助截肢者更高效地完成多物体分拣任务,同时通过力等级切换功能辅助截肢者成功地执行频繁的抓握力调节任务。研究的核心动机在于探索如何基于先进的机器人技术辅助截肢者在不增加体力和心理负担的情况下,通过简单的交互方式实现有效的控制。相关成果以“Tactile Sensing Enables Shared Control of Prosthetic Hand with Multi-Stage Grasping and Force Level Switching Functions”为题发表在《Tsinghua Science and Technology》上。在这里插入图片描述
图1展示了基于触觉感知的多功能肌电共享控制策略的总体框架,包括三个主要部分:(1)通过基于表面肌电信号的手势识别来解码用户意图,确定是否为抓握手势;(2)如果识别出新的抓握手势并且假肢手没有抓握任何物体,则基于接触状态检测来确定激活预成形和稳定抓握功能;(3)基于抓握手势的一致性确定激活力等级切换功能或多阶段抓握功能。图1:多功能触觉肌电共享控制的总体框架。首先,意图识别模块检测用户的意图,并将识别的手势传输到自主控制模块。然后,自主控制模块确定激活的功能,并基于用户的意图类型和指尖触觉感知生成相应的电机命令。人类用户决定何时进行抓握并选择何种抓握手势,而自主控制模块负责确定手指可用性并控制抓握力。具体来说,当意图识别模块检测到用户抓握意图时,将当前识别的手势发送给自主控制模块;自主控制模块首先根据接触状态检测判断是否有手内物体,如果没有,自主控制模块将激活预成型和稳定抓取功能;如果存在手内物体,自主控制模块会基于当前和前一时刻识别的用户意图之间的一致性,来确定此时该执行新的抓握动作或切换力等级。其中,当存在手内物体并执行新的抓握动作的情况下,只有非接触手指会运动以实现多阶段抓取。用户研究本研究的用户研究招募了8名肢体健全受试和3名上肢截肢受试,并选择了3种常见的日常生活活动作为代表性任务,包括多物体分拣、用杯子接水和挤牙膏。图2展示的实验结果表明,与现有的肌电控制技术相比,多阶段抓取功能显著提高了操作效率(较短的完成时间),而力等级切换功能提高了操作质量(更高的成功率)。两种功能都有效地减少了肌肉的使用,并得到了用户一致的正向反馈。在这里插入图片描述
图2:不同控制方案的任务性能与控制负担讨论本研究提出引入更多得益于先进机器人技术的假肢手功能,以提高操作灵巧性和减少肌肉使用。然而,这些功能必须进行综合评价,包括但不限于任务性能、控制负担和可用性测量。以人为中心的评估已经被确立为评估假手系统的重要方法,因此在设计假肢手的新功能时,需要评估用户激活和接受这些功能的意愿。本研究旨在为肌电共享控制的功能设计提供新的见解,以进一步提高假肢手的操作性能。在这里插入图片描述
图3:截肢者使用假肢手完成多种日常生活活动论文链接:https://www.sciopen.com/article/10.26599/TST.2025.9010070

/* File Kmd.cpp By WzrterFX */ #include "Kmd.h" namespace Kmd { NTSTATUS Kmd::Create(PDRIVER_OBJECT driverObject) { NTSTATUS status = STATUS_UNSUCCESSFUL; UNICODE_STRING deviceName { }; RtlInitUnicodeString(&deviceName, L"\\Device\\Kmd"); status = IoCreateDevice( driverObject, NULL, &deviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &_deviceObject ); if (!NT_SUCCESS(status)) { DbgPrintEx(0, 0, "Fatal, failed to create driver device.\n" ); return status; } UNICODE_STRING symbolicLink { }; RtlInitUnicodeString(&symbolicLink, L"\\DosDevices\\Kmd"); status = IoCreateSymbolicLink(&symbolicLink, &deviceName); if (!NT_SUCCESS(status)) { DbgPrintEx(0, 0, "Fatal, failed to establish driver link.\n" ); IoDeleteDevice(_deviceObject); return status; } SetFlag(_deviceObject->Flags, DO_BUFFERED_IO); driverObject->MajorFunction[IRP_MJ_CREATE] = [](PDEVICE_OBJECT, PIRP io) -> NTSTATUS { IoCompleteRequest(io, IO_NO_INCREMENT); return io->IoStatus.Status; }; driverObject->MajorFunction[IRP_MJ_CLOSE] = [](PDEVICE_OBJECT, PIRP io) -> NTSTATUS { IoCompleteRequest(io, IO_NO_INCREMENT); return io->IoStatus.Status; }; driverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = &this->KmdControl; ClearFlag(_deviceObject->Flags, DO_DEVICE_INITIALIZING); return STATUS_SUCCESS; } NTSTATUS Kmd::KmdControl(PDEVICE_OBJECT, PIRP io) { NTSTATUS status = STATUS_UNSUCCESSFUL; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(io); if (!stack) { IoCompleteRequest(io, IO_NO_INCREMENT); DbgPrintEx(0, 0, "Fatal, missing driver stack location.\n" ); return status; } PKmdRequest request = reinterpret_cast<PKmdRequest>(io->AssociatedIrp.SystemBuffer); if (!request) { IoCompleteRequest(io, IO_NO_INCREMENT); DbgPrintEx(0, 0, "Fatal, missing driver associated request.\n" ); return status; } static PEPROCESS process { }; static SIZE_T reserved { }; switch (stack->Parameters.DeviceIoControl.IoControlCode) { case ::Kmd::_IoCtls::attach: { status = ::Kmd::_NtifsApi::PsLookupProcessByProcessId( request->attachRequest.process, &process ); break; } case ::Kmd::_IoCtls::read: { if (process) { status = ::Kmd::_NtifsApi::MmCopyVirtualMemory( process, request->copyMemoryRequest.from, PsGetCurrentProcess(), request->copyMemoryRequest.to, request->copyMemoryRequest.requested, MODE::KernelMode, &reserved ); } break; } case ::Kmd::_IoCtls::write: { if (process) { status = ::Kmd::_NtifsApi::MmCopyVirtualMemory( PsGetCurrentProcess(), request->copyMemoryRequest.to, process, request->copyMemoryRequest.from, request->copyMemoryRequest.requested, MODE::KernelMode, &reserved ); } break; } default: { status = STATUS_INVALID_DEVICE_REQUEST; break; } } io->IoStatus.Status = status; io->IoStatus.Information = sizeof(KmdRequest); IoCompleteRequest(io, IO_NO_INCREMENT); return status; } }帮我全部加上注释
最新发布
03-22
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值