Realitykit结合Speech实现语音控制AR机器人移动(完整代码)

这篇具有很好参考价值的文章主要介绍了Realitykit结合Speech实现语音控制AR机器人移动(完整代码)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

利用Apple最新的Realitykit搭配ARkit实现虚拟物体的放置,结合内置的Speech库实现语音的识别功能,将语音内容转为文本内容,从而让机器进行运动。

大体思路:

1、配置并启动ARkit环境。

2、构建Entity实体。可以用Apple官方的CreatingAPhotogrammetryCommandLineApp的代码文档来生成.usdz文件,从而建造自己想要的实体。

3、放置实体到现实环境中。通过raycast发射射线,通过转化获得现实世界中的x,y,z的坐标,从而把实体放在现实世界中。

4、实现机器人的运动。通过传入文本信息,利用实体的transition属性来进行移动。

5、通过SFSpeechRecognizer获得语音识别允许。

6、创造音频节点,将输入语音的设备设置为麦克风,将音频结果初始化,放到SFSpeechAudioBufferRecognitionRequest里面。

7、进行音频结果的处理,转化为文本,放到机器人运动中。

8、机器人完成运动

没介绍的其他代码就是为实体添加属性,让机器人能够移动,放缩,旋转。

还有一些手势的识别:长按添加新的实体,滑动让实体消失。

import UIKit
import RealityKit
import ARKit
import Speech
class ViewController: UIViewController {
    @IBOutlet var arView: ARView!
    
    var entity: Entity?
    var moveToLocation: Transform = Transform()
    let moveTime: Double = 5
    //语音识别
    let speechRecognizer: SFSpeechRecognizer? = SFSpeechRecognizer()
    let speechRequest = SFSpeechAudioBufferRecognitionRequest()
    var speechTask = SFSpeechRecognitionTask()
    // 音频实例化
    let audioEngine = AVAudioEngine() //设立音频节点,处理音频输入和输出
    let audioSession = AVAudioSession() //音频记录初始化
    override func viewDidLoad() {
        super.viewDidLoad()
        entity = try! Entity.loadModel(named: "toy_robot_vintage.usdz")
        entity?.generateCollisionShapes(recursive: true)
        //包裹起来 增加碰撞属性
        arView.installGestures([.rotation,.scale,.translation], for: entity! as! HasCollision)
        //创建session
        startARSession()
        //创建手势 将2d位置转换为3d位置 获取位置传递到下面的函数中
        arView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTapLocation)))
        arView.addGestureRecognizer(UISwipeGestureRecognizer(target: self, action: #selector(handleSwipeLocation)))
        arView.addGestureRecognizer(UILongPressGestureRecognizer(target: self, action: #selector(handleLongPressLocation)))
        startSpeechRecognition()
        
    }
    @objc func handleTapLocation(_ recognizer:UITapGestureRecognizer){
        let tapLocation = recognizer.location(in: arView)
        //发射粒子 转化为3d坐标
        let result = arView.raycast(from: tapLocation, allowing: .estimatedPlane, alignment: .horizontal)
        //得到x,y,z坐标
        if let firstResult = result.first{
            let worldPosition = simd_make_float3(firstResult.worldTransform.columns.3)
            placeModelInWorld(object: entity!, position: worldPosition)
        }
    }
    @objc func handleSwipeLocation(_ recognizer: UISwipeGestureRecognizer){
        let longPressLocation = recognizer.location(in: arView)
        if let entity = arView.entity(at: longPressLocation){
            entity.anchor?.removeFromParent()
        }
    }
    @objc func handleLongPressLocation(_ recognizer: UILongPressGestureRecognizer){
        let doubleTapLocation = recognizer.location(in: arView)
        let result = arView.raycast(from: doubleTapLocation, allowing: .estimatedPlane, alignment: .horizontal)
        //得到x,y,z坐标
        if let firstResult = result.first{
            let worldPosition = simd_make_float3(firstResult.worldTransform.columns.3)
            if (arView.entity(at: doubleTapLocation) == nil){
                let objectAnchor = AnchorEntity(world: worldPosition)
                let entity1 = try! Entity.loadModel(named: "toy_robot_vintageOne.usdz")
                entity1.generateCollisionShapes(recursive: true)
                arView.installGestures([.translation,.rotation,.scale], for: entity1)
                objectAnchor.addChild(entity1)
                arView.scene.addAnchor(objectAnchor)
                
            }
        }
    }
    func startARSession(){
        arView.automaticallyConfigureSession = true
        let configuration = ARWorldTrackingConfiguration()
        configuration.planeDetection = [.horizontal]
        configuration.environmentTexturing = .automatic
//        arView.debugOptions = .showAnchorGeometry
        arView.session.run(configuration)
    }
    func placeModelInWorld(object:Entity,position:SIMD3<Float>){
        let objectAnchor = AnchorEntity(world: position)
        objectAnchor.addChild(object)
        arView.scene.addAnchor(objectAnchor)
    }
    func rebotMove(direction: String){
        switch direction{
        case "forward":
            moveToLocation.translation = (entity!.transform.translation)+simd_float3(x:0,y:0,z:20)
            entity!.move(to: moveToLocation, relativeTo: entity!, duration: moveTime)
            walkAnimation(movementDuration: moveTime)
            print("moveForward")
        case "back":
            moveToLocation.translation = (entity!.transform.translation)+simd_float3(x:0,y:0,z:-20)
            entity!.move(to: moveToLocation, relativeTo: entity!, duration: moveTime)
            walkAnimation(movementDuration: moveTime)
        case "left":
            let rotateToAngle = simd_quatf(angle: GLKMathDegreesToRadians(90), axis: SIMD3(x:0,y:1,z:0))
            entity!.setOrientation(rotateToAngle, relativeTo: entity!)
        case "right":
            let rotateToAngle = simd_quatf(angle: GLKMathDegreesToRadians(-90), axis: SIMD3(x:0,y:1,z:0))
            entity!.setOrientation(rotateToAngle, relativeTo: entity!)
        default:
            print("没有移动指令")
        }
    }
    func walkAnimation(movementDuration: Double){
        if let rebotAnimation = entity!.availableAnimations.first{
            entity!.playAnimation(rebotAnimation.repeat(duration: movementDuration),transitionDuration: 0.5,startsPaused: false)
            print("Yes")
        }else{
            print("没有相关动画")
        }
    }
    func startSpeechRecognition(){
        //获得允许
        requestPermission()
        //记录
        startAudioRecoding()
        //识别
        speechRecognize()
    }
    func requestPermission(){
        SFSpeechRecognizer.requestAuthorization { (authorizationStatus) in
            if(authorizationStatus  == .authorized){
                print("允许")
            }else if(authorizationStatus  == .denied){
                print("拒绝")
            }else if(authorizationStatus == .notDetermined){
                print("等待您的决定")
            }else if(authorizationStatus == .restricted){
                print("无法启用")
            }
        }
    }
    func startAudioRecoding(){
        //创造输入节点
        let node = audioEngine.inputNode
        let recordingFormate = node.outputFormat(forBus: 0)
        node.installTap(onBus: 0, bufferSize: 1024, format: recordingFormate) { (buffer, _) in
            self.speechRequest.append(buffer)
        }
        //启动引擎
        
        do{
            //配置音频会话为从麦克风录制
            try audioSession.setCategory(.record,mode: .measurement,options: .duckOthers)
            try audioSession.setActive(true,options: .notifyOthersOnDeactivation)
            audioEngine.prepare()
            try audioEngine.start()
        }
        catch{
            
        }
        
    }
    func speechRecognize(){
        guard let speechRecognizer = SFSpeechRecognizer()else{
            print("语音识别不可用")
            return
        }
        if (speechRecognizer.isAvailable == false){
            print("无法正常工作")
        }
        var count = 0
        speechTask = speechRecognizer.recognitionTask(with: speechRequest, resultHandler: { (result, error) in
            count += 1
            if(count == 1){
                guard let result = result else {
                    return
                }
                let recognizedText = result.bestTranscription.segments.last
                self.rebotMove(direction: recognizedText!.substring)
                print(recognizedText!.substring)
            }else if(count>=3){
                count = 0
            }
        })
    }
}

注释已经放在代码中了,只需要导入自己的.usdz文件就可以运行成功了。文章来源地址https://www.toymoban.com/news/detail-421137.html

到了这里,关于Realitykit结合Speech实现语音控制AR机器人移动(完整代码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包