【征文计划】AR健身教练:形随心动 - 基于Rokid CXR-M SDK的实践落地

【征文计划】AR健身教练:形随心动 - 基于Rokid CXR-M SDK的实践落地

一、项目背景与创意起源

在当今快节奏的都市生活中,健身已成为许多人保持健康的重要方式。然而,居家健身面临一个普遍痛点:缺乏专业指导,容易因动作不规范导致运动损伤,同时低头看手机或平板的体验也大大降低了健身的沉浸感和效率。

根据《2024年中国健身行业白皮书》显示,超过65%的居家健身用户表示"缺乏专业指导"是他们放弃健身的主要原因。而Rokid Glasses作为一款轻量级AR眼镜,其独特的"抬头即见"交互方式,为解决这一问题提供了绝佳的硬件基础。

"形随心动"创意的诞生源于一个简单但关键的观察:如果能将专业教练"投射"到用户视野中,实时指导动作,同时提供直观的数据反馈,那么居家健身体验将发生质的飞跃。通过Rokid CXR-M SDK的AI场景、自定义页面和提词器功能,我们能够实现这一愿景。


二、Rokid CXR-M SDK 相关

1. Rokid CXR-M SDK介绍

CXR-M SDK 是面向移动端的开发工具包,主要用于构建手机端与 Rokid Glasses 的控制和协同应用。开发者可以通过 CXR-M SDK 与眼镜建立稳定连接,实现数据通信、实时音视频获取以及场景自定义。它适合需要在手机端进行界面交互、远程控制或与眼镜端配合完成复杂功能的应用。目前 CXR-M SDK 仅提供 Android 版本。

2. SDK 开发导入配置

1. 配置Maven仓库

CXR-M SDK 采用 Maven 在线管理SDK Package

Maven 仓库地址:(“https://maven.rokid.com/repository/maven-public/”)

找到settings.gradle.kts,并在dependencyResolutionManagement节点的repositories 中添加Maven仓库。

2. 依赖导入

CXR-M SDK Package(“com.rokid.cxr:client-m:1.0.1-20250812.080117-2”)。

在build.gradle.kts 的dependencies 节点中添加依赖。

注意:SDK 需要设置minSdk≥28

如果和项目中已有版本冲突,请优先选用SDK 中对应的版本

3. 权限申请

1. 声明权限

CXR-M SDK 需要申请网络、Wi-Fi、Bluetooth(蓝牙权限需要同步申请FINE_LOCATION 权限) 等权限,在AndroidManifest.xml 中申请以下是最小权限集:

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <application> <!--Other Settings--> </application> </manifest>

2. 动态申请权限

在CXR-M SDK 使用前,请先进行必要权限动态申请。注意在权限不足的情况下,SDK 将不可用。

示例:

class MainActivity : AppCompatActivity() { companion object { const val TAG = "MainActivity" // Request Code const val REQUEST_CODE_PERMISSIONS = 100 // Required Permissions private val REQUIRED_PERMISSIONS = mutableListOf( Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_ADMIN, ).apply { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { add(Manifest.permission.BLUETOOTH_SCAN) add(Manifest.permission.BLUETOOTH_CONNECT) } }.toTypedArray() } // Permission private val permissionGrantedResult = MutableLiveData<Boolean?>() override fun onCreate(savedInstanceState: Bundle?) { // Other Code // Request Permissions permissionGrantedResult.postValue(null) requestPermissions(REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS) // Observe Permission Result permissionGrantedResult.observe(this) { if (it == true) { // Permission All Granted }else{ // Some Permission Denied or Not Started } } } override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == REQUEST_CODE_PERMISSIONS.hashCode()){ val allGranted = grantResults.all { it == PackageManager.PERMISSION_GRANTED} permissionGrantedResult.postValue(allGranted) } } } 

三、技术架构设计

1. 整体架构

"形随心动"采用分层架构设计,确保系统稳定性和可扩展性:

应用层(Android App) → CXR-M SDK → Rokid Glasses(YodaOS) → 硬件传感器
  • 应用层:提供用户界面、健身计划管理、社交功能
  • CXR-M SDK:负责与Rokid Glasses的通信、AI场景处理、AR界面渲染
  • Rokid Glasses:执行AR渲染、动作捕捉、数据反馈
  • 硬件传感器:提供身体姿态、心率等数据

"形随心动"应用的整体技术架构:

架构说明:

  • 应用层:包含用户界面、健身计划管理、社交功能等业务逻辑
  • CXR-M SDK:Rokid提供的核心SDK,负责与硬件通信和功能调用
  • Rokid Glasses:硬件平台,执行AR渲染和传感器数据处理
  • 硬件传感器:提供摄像头、IMU、心率等原始数据
  • AR界面:通过自定义页面实现的AR可视化展示
  • AI场景:利用CXR-M SDK的AI能力实现动作识别
  • 自定义页面:用于创建AR交互界面的核心组件
  • 社交互动模块:实现好友挑战、进度分享等功能

CXR SDK 与Glasses 架构

2. 核心组件设计

组件

功能

SDK实现方式

实时动作识别模块

通过摄像头捕捉用户动作,分析动作质量

AI场景、自定义页面

个性化计划模块

根据用户数据定制健身计划

自定义页面、数据同步

AR教练界面

3D显示虚拟教练,实时指导动作

自定义页面、提词器

数据可视化模块

实时显示心率、消耗卡路里等数据

自定义页面、媒体操作

社交互动模块

支持好友挑战、进度分享

数据通信、自定义页面

核心组件交互关系图:

3. 架构设计优势

  1. 分层解耦设计
    • 业务逻辑与硬件交互完全分离
    • 各组件通过SDK接口通信,降低耦合度
    • 方便后续功能扩展和维护
  1. 硬件能力充分利用
    • 摄像头:用于动作捕捉
    • IMU传感器:辅助动作分析
    • AR显示:提供沉浸式指导体验
    • 语音交互:实现自然的人机对话
  1. SDK能力深度整合
    • AI场景:实现核心动作识别功能
    • 自定义页面:构建AR交互界面
    • 提词器场景:实现简单文字指导
    • 数据通信:支持社交功能
  1. 可扩展性设计
    • 新功能只需新增模块,不影响现有架构
    • 通过SDK接口扩展,无需修改底层硬件
    • 支持未来硬件升级和新功能添加

实现关键点:

组件

关键技术点

SDK实现方式

实现难度

设备连接

蓝牙稳定连接

CxrApi.getInstance().initBluetooth()

★★☆

AI场景

动作识别与分析

setAiEventListener()

+ controlScene()

★★★★

AR界面

3D指导界面渲染

openCustomView()

+ JSON布局

★★★

数据同步

实时数据传输

sendStream()

+ setMediaFilesUpdateListener()

★★

社交功能

好友挑战实现

controlScene()

+ 数据通信

★★★


四、关键功能实现详解

1. 设备连接与初始化

首先,需要确保手机与Rokid Glasses稳定连接,这是所有功能的基础。

// 设备连接初始化 class FitnessApp : AppCompatActivity() { private val REQUIRED_PERMISSIONS = mutableListOf( Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_ADMIN, ).apply { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { add(Manifest.permission.BLUETOOTH_SCAN) add(Manifest.permission.BLUETOOTH_CONNECT) } }.toTypedArray() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 检查并请求必要权限 if (!hasPermissions(REQUIRED_PERMISSIONS)) { requestPermissions(REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS) } else { initializeDeviceConnection() } } private fun hasPermissions(permissions: Array<String>): Boolean { return permissions.all { ContextCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED } } private fun initializeDeviceConnection() { // 查找Rokid设备 val scanner = BluetoothLeScannerCompat.getScanner() scanner.startScan( listOf(ScanFilter.Builder() .setServiceUuid(ParcelUuid.fromString("00009100-0000-1000-8000-00805f9b34fb")) .build()), ScanSettings.Builder().build(), scanCallback ) } private val scanCallback = object : ScanCallback() { override fun onScanResult(callbackType: Int, result: ScanResult) { super.onScanResult(callbackType, result) val device = result.device // 找到设备后,初始化蓝牙连接 CxrApi.getInstance().initBluetooth(this@FitnessApp, device, object : BluetoothStatusCallback { override fun onConnectionInfo(socketUuid: String?, macAddress: String?, rokidAccount: String?, glassesType: Int) { Log.d("FitnessApp", "Connection info: $socketUuid, $macAddress, $rokenAccount, $glassesType") // 初始化成功后,连接蓝牙 CxrApi.getInstance().connectBluetooth(this@FitnessApp, socketUuid, macAddress, this@FitnessApp) } override fun onConnected() { Log.d("FitnessApp", "Bluetooth connected successfully") // 连接成功后,初始化AI场景 initializeAiScene() } override fun onDisconnected() { Log.e("FitnessApp", "Bluetooth disconnected") } override fun onFailed(errorCode: ValueUtil.CxrBluetoothErrorCode?) { Log.e("FitnessApp", "Bluetooth connection failed: $errorCode") } }) } } private fun initializeAiScene() { // 设置AI事件监听 CxrApi.getInstance().setAiEventListener(object : AiEventListener { override fun onAiEvent(eventType: ValueUtil.CxrAiEventType?, data: String?) { when (eventType) { ValueUtil.CxrAiEventType.ACTION_RECOGNITION -> { // 处理动作识别结果 handleActionRecognition(data) } // 其他事件类型处理 } } }) // 启动AI场景 CxrApi.getInstance().controlScene(ValueUtil.CxrSceneType.AI_SCENE, true, null) } }

2. 实时动作捕捉与纠正

这是"形随心动"的核心功能,利用Rokid Glasses的摄像头和AI能力,实时分析用户动作。

// 动作识别与纠正实现 private fun startExercise(exerciseType: String) { // 设置动作识别参数 val actionParams = HashMap<String, String>() actionParams["exerciseType"] = exerciseType actionParams["threshold"] = "0.85" // 识别阈值 // 启动AI场景进行动作识别 CxrApi.getInstance().controlScene( ValueUtil.CxrSceneType.AI_SCENE, true, actionParams ) // 设置AI事件监听 CxrApi.getInstance().setAiEventListener(object : AiEventListener { override fun onAiEvent(eventType: ValueUtil.CxrAiEventType?, data: String?) { when (eventType) { ValueUtil.CxrAiEventType.ACTION_RECOGNITION -> { val recognitionResult = Gson().fromJson(data, ActionRecognitionResult::class.java) if (recognitionResult.accuracy > 0.8) { // 动作正确,显示正面反馈 showPositiveFeedback(recognitionResult.exerciseName, "动作标准!") } else { // 动作不标准,显示纠正提示 showCorrectionFeedback(recognitionResult.exerciseName, recognitionResult.correctionMessage) } } } } }) } private fun showCorrectionFeedback(exerciseName: String, message: String) { // 通过提词器场景显示纠正信息 CxrApi.getInstance().controlScene( ValueUtil.CxrSceneType.WORD_TIPS, true, null ) // 设置提词器文字 val text = "动作纠正:$message" CxrApi.getInstance().sendStream( ValueUtil.CxrStreamType.WORD_TIPS, text.toByteArray(), "correction_text", object : SendStatusCallback { override fun onSendSucceed() { Log.d("FitnessApp", "Correction message sent successfully") } override fun onSendFailed(errorCode: ValueUtil.CxrSendErrorCode?) { Log.e("FitnessApp", "Failed to send correction message: $errorCode") } } ) } // 自定义页面场景:AR教练界面 private fun setupARCoachInterface() { // 创建AR教练界面的JSON布局 val" { "type": "LinearLayout", "props": { "layout_width": "match_parent", "layout_height": "match_parent", "orientation": "vertical", "gravity": "center_horizontal", "paddingTop": "140dp", "paddingBottom": "100dp", "backgroundColor": "#00000000" }, "children": [ { "type": "TextView", "props": { "id": "tv_instruction", "layout_width": "wrap_content", "layout_height": "wrap_content", "text": "请保持背部挺直", "textSize": "18sp", "textColor": "#FF00FF00", "textStyle": "bold", "marginBottom": "20dp" } }, { "type": "TextView", "props": { "id": "tv_count", "layout_width": "wrap_content", "layout_height": "wrap_content", "text": "0/10", "textSize": "24sp", "textColor": "#FFFFFFFF", "textStyle": "bold", "marginBottom": "30dp" } } ] } """.trimIndent() // 打开自定义页面 CxrApi.getInstance().openCustomView(arCoachJson) // 设置自定义页面状态监听 CxrApi.getInstance().setCustomViewListener(object : CustomViewListener { override fun onCustomViewOpened() { Log.d("FitnessApp", "Custom view opened successfully") } override fun onCustomViewClosed() { Log.d("FitnessApp", "Custom view closed") } }) }

3. 个性化健身计划

根据用户输入的身体数据和健身目标,定制专属健身计划。

// 个性化健身计划实现 class PersonalizedPlanActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_personalized_plan) // 获取用户输入数据 val age = findViewById<EditText>(R.id.et_age).text.toString().toInt() val weight = findViewById<EditText>(R.id.et_weight).text.toString().toFloat() val height = findViewById<EditText>(R.id.et_height).text.toString().toFloat() val goal = findViewById<Spinner>(R.id.spinner_goal).selectedItem.toString() // 根据数据生成计划 val plan = generatePersonalizedPlan(age, weight, height, goal) // 显示计划 displayPlan(plan) // 保存计划到Rokid Glasses savePlanToGlasses(plan) } private fun generatePersonalizedPlan(age: Int, weight: Float, height: Float, goal: String): Plan { // 实际应用中,这里会根据算法生成计划 // 为简化示例,直接返回预设计划 return Plan( "30天减脂计划", listOf( Exercise("深蹲", "3组×15次", "保持膝盖不超过脚尖", "squats"), Exercise("平板支撑", "3组×30秒", "保持身体成直线", "plank"), Exercise("跳绳", "3组×2分钟", "保持手腕放松", "jump_rope") ) ) } private fun displayPlan(plan: Plan) { val planAdapter = PlanAdapter(plan.exercises) findViewById<RecyclerView>(R.id.rv_plan).adapter = planAdapter } private fun savePlanToGlasses(plan: Plan) { // 将计划数据发送到Rokid Glasses val planJson = Gson().toJson(plan) CxrApi.getInstance().sendStream( ValueUtil.CxrStreamType.PERSONALIZED_PLAN, planJson.toByteArray(), "fitness_plan", object : SendStatusCallback { override fun onSendSucceed() { Log.d("FitnessApp", "Plan sent to glasses successfully") } override fun onSendFailed(errorCode: ValueUtil.CxrSendErrorCode?) { Log.e("FitnessApp", "Failed to send plan: $errorCode") } } ) } }

4. 数据可视化与实时反馈

将健身数据以AR形式展示,让用户无需低头即可获取关键信息。

// 数据可视化与实时反馈 class DataVisualizationActivity : AppCompatActivity() { private var heartRate = 0 private var caloriesBurned = 0f private var exerciseTime = 0 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_data_visualization) // 初始化AR界面 setupARDataView() // 开始计时 startExerciseTimer() // 模拟数据更新 startDataUpdates() } private fun setupARDataView() { // 创建AR数据视图的JSON布局 val" { "type": "LinearLayout", "props": { "layout_width": "match_parent", "layout_height": "match_parent", "orientation": "vertical", "gravity": "center", "backgroundColor": "#00000000" }, "children": [ { "type": "TextView", "props": { "id": "tv_heart_rate", "layout_width": "wrap_content", "layout_height": "wrap_content", "text": "心率: 72", "textSize": "20sp", "textColor": "#FF00FF00", "textStyle": "bold" } }, { "type": "TextView", "props": { "id": "tv_calories", "layout_width": "wrap_content", "layout_height": "wrap_content", "text": "卡路里: 0", "textSize": "20sp", "textColor": "#FF00FF00", "textStyle": "bold", "marginTop": "20dp" } }, { "type": "TextView", "props": { "id": "tv_time", "layout_width": "wrap_content", "layout_height": "wrap_content", "text": "时间: 00:00", "textSize": "20sp", "textColor": "#FF00FF00", "textStyle": "bold", "marginTop": "20dp" } } ] } """.trimIndent() // 打开自定义页面 CxrApi.getInstance().openCustomView(dataViewJson) } private fun updateDataView() { // 更新AR界面数据 val updateData = listOf( UpdateAction("update", "tv_heart_rate", "text", "心率: $heartRate"), UpdateAction("update", "tv_calories", "text", "卡路里: $caloriesBurned"), UpdateAction("update", "tv_time", "text", "时间: ${formatTime(exerciseTime)}") ) CxrApi.getInstance().updateCustomView(Gson().toJson(updateData)) } private fun formatTime(seconds: Int): String { val minutes = seconds / 60 val remainingSeconds = seconds % 60 return String.format("%02d:%02d", minutes, remainingSeconds) } private fun startDataUpdates() { // 每2秒更新一次数据 val handler = Handler(Looper.getMainLooper()) handler.postDelayed(object : Runnable { override fun run() { // 模拟数据更新 heartRate = (heartRate + 2).coerceAtMost(160) caloriesBurned += 0.5f exerciseTime += 2 updateDataView() handler.postDelayed(this, 2000) } }, 2000) } private fun startExerciseTimer() { // 开始健身计时 val startTime = System.currentTimeMillis() // 每秒更新时间 val timerHandler = Handler(Looper.getMainLooper()) timerHandler.postDelayed(object : Runnable { override fun run() { exerciseTime = ((System.currentTimeMillis() - startTime) / 1000).toInt() updateDataView() timerHandler.postDelayed(this, 1000) } }, 1000) } }

5. 社交健身挑战

通过Rokid Glasses的社交功能,实现与好友的健身互动。

// 社交健身挑战实现 class ChallengeActivity : AppCompatActivity() { private val challenges = mutableListOf<Challenge>( Challenge("7天深蹲挑战", "完成7天深蹲训练,每天100次", 7, 100), Challenge("30天心率挑战", "保持心率在120-150之间", 30, 0) ) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_challenge) // 显示挑战列表 setupChallengeList() // 添加好友挑战 findViewById<Button>(R.id.btn_add_friend_challenge).setOnClickListener { showAddFriendChallengeDialog() } } private fun setupChallengeList() { val adapter = ChallengeAdapter(challenges) findViewById<RecyclerView>(R.id.rv_challenges).adapter = adapter } private fun showAddFriendChallengeDialog() { val builder = AlertDialog.Builder(this) builder.setTitle("添加好友挑战") val input = EditText(this) input.hint = "输入好友ID" builder.setView(input) builder.setPositiveButton("确定") { _, _ -> val friendId = input.text.toString() createFriendChallenge(friendId) } builder.setNegativeButton("取消", null) builder.show() } private fun createFriendChallenge(friendId: String) { // 创建好友挑战 val challenge = Challenge( "与$friendId的挑战", "一起完成30天健身挑战", 30, 0 ) // 保存挑战到Rokid Glasses saveChallengeToGlasses(challenge) // 同步挑战到好友 sendChallengeToFriend(friendId, challenge) } private fun saveChallengeToGlasses(challenge: Challenge) { val challengeJson = Gson().toJson(challenge) CxrApi.getInstance().sendStream( ValueUtil.CxrStreamType.CHALLENGE, challengeJson.toByteArray(), "challenge_${challenge.id}", object : SendStatusCallback { override fun onSendSucceed() { Log.d("FitnessApp", "Challenge saved to glasses") } override fun onSendFailed(errorCode: ValueUtil.CxrSendErrorCode?) { Log.e("FitnessApp", "Failed to save challenge: $errorCode") } } ) } private fun sendChallengeToFriend(friendId: String, challenge: Challenge) { // 实际应用中,这里会通过Rokid社交API发送挑战 // 为简化示例,直接模拟成功 Log.d("FitnessApp", "Challenge sent to friend $friendId") // 显示成功提示 Toast.makeText(this, "挑战已发送给好友 $friendId", Toast.LENGTH_SHORT).show() } }

五、挑战与解决方案

1. 动作识别精度问题

挑战:在实际环境中,由于光线变化和用户动作差异,AI动作识别准确率有时不足。

解决方案

  • 采用多模态数据融合:结合摄像头和Rokid Glasses的传感器数据
  • 实现动态阈值调整:根据用户身体特征自动调整识别阈值
  • 添加用户反馈机制:允许用户确认或纠正AI识别结果
// 动态阈值调整示例 private fun adjustRecognitionThreshold(userProfile: UserProfile): Float { return when { userProfile.age < 25 -> 0.85f userProfile.age < 40 -> 0.80f else -> 0.75f } }

2. AR界面流畅度优化

挑战:AR界面在Rokid Glasses上运行时,帧率不稳定。

解决方案

  • 优化自定义页面JSON布局,减少不必要的元素
  • 使用CXR-M SDK的setCustomViewListener进行界面渲染优化
  • 采用异步数据更新,避免阻塞主线程
// 优化AR界面渲染 CxrApi.getInstance().setCustomViewListener(object : CustomViewListener { override fun onCustomViewOpened() { // 优化渲染 CxrApi.getInstance().setCustomViewRenderMode(ValueUtil.CxrRenderMode.FAST) } override fun onCustomViewClosed() { // 恢复默认渲染模式 CxrApi.getInstance().setCustomViewRenderMode(ValueUtil.CxrRenderMode.DEFAULT) } })

3. 电池消耗问题

挑战:AR应用长时间运行导致Rokid Glasses电池消耗过快。

解决方案

  • 实现智能功耗管理:根据使用场景动态调整功耗
  • 添加自动休眠功能:用户停止运动一段时间后自动进入低功耗模式
  • 优化数据传输:减少不必要的数据同步
// 智能功耗管理 CxrApi.getInstance().setPowerOffTimeout(30) // 30分钟后自动关机 CxrApi.getInstance().setScreenOffTimeout(60) // 60秒后屏幕关闭 // 自动休眠功能 val exerciseTimer = object : CountDownTimer(300000, 1000) { // 5分钟 override fun onTick(millisUntilFinished: Long) { // 更新休眠计时 } override fun onFinish() { // 进入低功耗模式 CxrApi.getInstance().setGlassBrightness(3) // 降低亮度 CxrApi.getInstance().setGlassVolume(2) // 降低音量 Toast.makeText(this@FitnessApp, "进入低功耗模式", Toast.LENGTH_SHORT).show() } }.start()

六、未来展望

"形随心动"已经证明了Rokid CXR-M SDK在AR健身场景中的强大能力,未来我们将进一步拓展:

  1. AI能力增强:集成更先进的动作识别模型,提升识别精度
  2. 内容生态扩展:与专业健身教练合作,提供更多高质量课程
  3. 硬件联动:与智能健身设备联动,获取更全面的运动数据
  4. 跨平台支持:拓展到更多Rokid硬件设备,形成完整的AR健身生态

七、结语

"形随心动"不仅是一款健身应用,更是Rokid CXR-M SDK能力的全面展示。通过深度整合SDK的AI场景、自定义页面和提词器功能,我们实现了真正"抬头即见指导"的AR健身体验,解决了居家健身的核心痛点。

"形随心动"展示了Rokid生态的广阔应用前景,也为其他开发者提供了可借鉴的实践案例。我们相信,随着Rokid SDK的持续完善和生态的不断扩展,AR技术将在更多生活场景中发挥重要作用,为用户带来前所未有的体验。

通过"形随心动"的实践,我们验证了Rokid Glasses与CXR-M SDK在AI+AR场景中的巨大潜力,也为Rokid开发者社区贡献了一个成功的应用案例。未来,我将继续深耕AR健身领域,为用户提供更专业、更智能的健身体验,同时为Rokid生态的繁荣贡献力量。

Read more

XIlinx FPGA使用LVDS的电源与电平关键指南

XIlinx FPGA使用LVDS的电源与电平关键指南

针对 7 Series, UltraScale, UltraScale+ FPGAs 以及 MPSoC 器件使用 LVDS 的注意事项: 1. 适用范围 * 器件系列:7 Series, UltraScale, UltraScale+, Zynq UltraScale+ MPSoC。 * 涉及 IO 类型:High Performance (HP) Banks, High Range (HR) Banks, High Density (HD) Banks。 2. 电源电压 (VCCO) 与 输入/输出 的限制 这是该指南的核心内容,根据 Bank 类型和是用作输入还是输出,规则有所不同: A. LVDS

喂饭级教程:OpenClaw 对接 QQ 机器人,本地/腾讯云都能用

喂饭级教程:OpenClaw 对接 QQ 机器人,本地/腾讯云都能用

文章目录 * 前言 * 一、选对路子:官方 Bot 还是个人号? * 方案 A:QQ 开放平台官方机器人 * 方案 B:个人 QQ 号变身机器人 * 二、环境准备:5 分钟搞定基础设施 * 1. 服务器/电脑要求 * 2. 安装 OpenClaw * 3. 配置大模型 API * 三、方案 A:对接 QQ 开放平台官方机器人 * Step 1:注册开发者并创建机器人 * Step 2:获取三件套凭证 * Step 3:配置 IP 白名单和沙箱 * Step 4:OpenClaw 端配置

AI 辅助开发实战:基于树莓派智能家居毕设的高效构建与避坑指南

在基于树莓派的智能家居毕业设计中,很多同学都遇到过相似的困境:树莓派算力有限,跑个复杂的AI模型就卡顿;传感器数据五花八门,处理起来容易出错;想把模型部署到边缘端,步骤繁琐,调试过程更是让人头大。整个项目就像在走钢丝,既要保证功能,又要兼顾性能和稳定性。 最近,我尝试将AI辅助开发工具和轻量级AI推理框架结合起来,重新梳理了整个开发流程,发现效率提升非常明显。这篇文章,我就来分享一下如何利用这些工具,高效、稳定地构建一个智能家居毕设系统,并附上一些实践中总结的“避坑”经验。 1. 背景与核心痛点:为什么需要AI辅助开发? 传统的树莓派智能家居项目开发,通常有几个绕不开的难题: * 硬件资源捉襟见肘:树莓派(尤其是Zero或3B+等型号)的内存和CPU性能有限。直接部署未经优化的TensorFlow或PyTorch模型,很容易导致系统响应迟缓甚至崩溃。 * 模型部署“从入门到放弃”:将PC上训练好的模型移植到ARM架构的树莓派上,涉及框架版本、依赖库、算子兼容性等一系列问题,环境配置就能耗掉大量时间。 * 调试过程“黑盒”化:当系统集成传感器、执行器、网络服务和AI推理后,

[论文阅读] AI + 软件工程 | 突破LLM代码生成瓶颈:编程知识图谱(PKG)让检索增强更精准

[论文阅读] AI + 软件工程 | 突破LLM代码生成瓶颈:编程知识图谱(PKG)让检索增强更精准

突破LLM代码生成瓶颈:编程知识图谱(PKG)让检索增强更精准 论文信息 * 原标题:Context-Augmented Code Generation Using Programming Knowledge Graphs(基于编程知识图谱的上下文增强代码生成) * 主要作者及研究机构: * Shahd Seddik、Fahd Seddik、Iman Saberi、Fatemeh Fard(加拿大不列颠哥伦比亚大学) * Minh Hieu Huynh、Patanamon Thongtanunam(澳大利亚墨尔本大学) * 引文格式(GB/T 7714): Seddik S, Seddik F, Saberi I, et al. Context-Augmented Code Generation Using Programming Knowledge Graphs[J]