什么东西都很容易忘记,大杂烩开始了——也许都不是原创,但真的需要加些东西帮助记忆了

博主表示刚看过的东西下次想用就忘,很是痛苦,因此打算记录自己感兴趣的内容。

之前刚刚看的东西,下次想用的时候就忘了,真是痛苦啊

记录我感兴趣的内容

MATLAB主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性内容概要:本文主要介绍了一种在MATLAB环境下实现的主动噪声和振动控制算法,该算法针对较大的次级路径变化具有较强的鲁棒性。文中详细阐述了算法的设计原理与实现方法,重点解决了传统控制系统中因次级路径动态变化导致性能下降的问题。通过引入自适应机制和鲁棒控制策略,提升了系统在复杂环境下的稳定性和控制精度,适用于需要高精度噪声与振动抑制的实际工程场景。此外,文档还列举了多个MATLAB仿真实例及相关科研技术服务内容,涵盖信号处理、智能优化、机器学习等多个交叉领域。; 适合人群:具备一定MATLAB编程基础和控制系统理论知识的科研人员及工程技术人员,尤其适合从事噪声与振动控制、信号处理、自动化等相关领域的研究生和工程师。; 使用场景及目标:①应用于汽车、航空航天、精密仪器等对噪声和振动敏感的工业领域;②用于提升现有主动控制系统对参数变化的适应能力;③为相关科研项目提供算法验证与仿真平台支持; 阅读建议:建议读者结合提供的MATLAB代码进行仿真实验,深入理解算法在不同次级路径条件下的响应特性,并可通过调整控制参数进一步探究其鲁棒性边界。同时可参考文档中列出的相关技术案例拓展应用场景。
明白了!以下是你需要的 **正确格式、清晰结构、完整可运行** 的 Auto.js 脚本,已根据你的需求进行 **全面修正与优化**,确保: - ✅ 逻辑严谨 - ✅ 函数前置 - ✅ 去重准确(名称 + 押金) - ✅ 避免重复代码 - ✅ 格式规范(无冗余、缩进统一、注释清晰) --- ```js // ======== 1. 初始化设置 ========== auto.waitFor(); device.keepScreenDim(); setScreenMetrics(1236, 2676); if (!requestScreenCapture()) { toast("❌ 请求截图权限失败"); exit(); } toast("✅ 脚本启动,请进入商品列表页..."); // ======== 2. 全局变量定义 ========== const LIST_PAGE_ID = "recyclerview"; // RecyclerView 的 ID const DEPOSIT_ID = "min_deposit_tv"; // 押金控件 ID const NAME_ID = "name_tv"; // 名称控件 ID const MAX_WAIT_SECONDS = 20; // 等待超时时间 const CSV_FILE_PATH = "/sdcard/Aac_report.csv"; // CSV 文件路径 let processedKeys = {}; // 已处理项去重表 let successCount = 0; // 成功记录条数 // 创建文件目录 const File = java.io.File; const parentDir = new File(CSV_FILE_PATH).getParentFile(); if (!parentDir.exists()) parentDir.mkdirs(); console.info("📁 日志文件路径: " + CSV_FILE_PATH); // ======== 3. 工具函数定义 ========== /** * 从文本中提取数字(支持中文符号) */ function extractNumber(text) { if (typeof text === 'undefined' || text === null) return null; const clean = String(text).replace(/[^\d.]/g, ''); const num = parseFloat(clean); return isNaN(num) ? null : num; } /** * 四舍五入到指定位数 */ function round(num, digits = 2) { const factor = Math.pow(10, digits); return Math.round(num * factor) / factor; } /** * 字符串归一化(用于构造唯一键) */ function normalizeString(str) { if (typeof str !== 'string') str = String(str); return str.trim().toLowerCase() .replace(/\s+/g, ' ') .replace(/[^\w\u4e00-\u9fa5]/g, ''); } /** * 等待列表页出现 */ function waitForListPage(timeout = MAX_WAIT_SECONDS * 1000) { const start = new Date().getTime(); while (new Date().getTime() - start < timeout) { if (id(LIST_PAGE_ID).exists()) { const widget = id(LIST_PAGE_ID).findOnce(); if (widget && widget.visibleToUser()) { log("✅ 列表页就绪"); return true; } } sleep(500); } log("❌ 等待列表页超时"); return false; } /** * 获取详情页中的物品名称 */ function getTaskName() { try { const w = id("tv_order_details_title").findOne(3000); const name = (w?.text() || w?.desc() || "未知物品").trim(); log(`📋 物品名称: ${name}`); return name; } catch (e) { log("⚠️ 获取名称失败: " + e.message); return "异常物品"; } } /** * 获取“我的售价” */ function getSellingPrice() { try { const w = id("tv_selling_price_value").findOne(5000); if (!w) return null; const raw = w.text(); const price = extractNumber(raw); if (price === null) { log("❌ 解析售价失败: " + raw); return null; } log(`✅ 我的售价: ¥${price}`); return price; } catch (e) { log("⚠️ 获取售价异常: " + e.message); return null; } } /** * 获取当前选中的分类容器 */ function getCurrentCategoryContainer() { const list = id("item_category_ll").className("android.view.ViewGroup").find(); for (let i = 0; i < list.size(); i++) { const c = list.get(i); try { if (c.clickable() && c.selected()) { return c; } } catch (e) {} } return null; } /** * 从分类容器中提取定价 */ function extractPricingFrom(parent) { try { const children = parent.children(); for (let i = 0; i < children.size(); i++) { const ch = children.get(i); const t = (ch.text() || ch.desc() || ""); const num = extractNumber(t); if (num !== null) { return { value: num, rawText: t }; } } } catch (e) { log("⚠️ 提取定价失败: " + e.message); } return null; } /** * 获取磨损等级 */ function getWearLevel() { try { const w = id("tv_abrade_filter").findOne(2000); return w ? (w.text() || "未获取") : "未获取"; } catch (e) { return "获取失败"; } } /** * 上滑载更多 */ function swipeUp() { const h = device.height; const w = device.width; try { gesture(500, [w/2, h*0.7], [w/2, h*0.3]); sleep(1500); return true; } catch (e) { return false; } } /** * 图像识别点击:磨损区间 & 磨损度 */ function performImageClicks() { log("🖼️ 执行图像识别操作"); // 点击“磨损区间” if (text("磨损区间").exists()) { const cap = captureScreen(); const tem = images.read("/sdcard/脚本/小图/磨损区间.png"); if (tem) { const p = images.findImage(cap, tem, { region: [206, 987, 142, 177], threshold: 0.9 }); if (p) { click(p.x + tem.getWidth()/2, p.y + tem.getHeight()/2); log("🖱️ 已点击:磨损区间"); sleep(1000); } cap.recycle(); tem.recycle(); } else { log("❌ 模板图片不存在: 磨损区间.png"); } } // 点击“磨损度” sleep(1000); const cap1 = captureScreen(); const tem1 = images.read("/sdcard/脚本/小图/磨损度.png"); if (tem1) { const p1 = images.findImage(cap1, tem1, { region: [27, 1089, 93, 184], threshold: 0.9 }); if (p1) { click(p1.x + tem1.getWidth()/2 + 47, p1.y + tem1.getHeight()/2 + 136); log("🖱️ 已点击:磨损度"); } cap1.recycle(); tem1.recycle(); } } /** * 采集数据并写入 CSV */ function collectAndSaveData() { const taskName = getTaskName(); const sellingPrice = getSellingPrice(); if (!sellingPrice) { toast("⚠️ 售价获取失败,跳过"); return false; } const container = getCurrentCategoryContainer(); if (!container) { toast("🚫 未找到选中分类"); return false; } const pricing = extractPricingFrom(container); if (!pricing) { toast("⚠️ 分类无有效定价"); return false; } const categoryPrice = pricing.value; const diff = round(Math.abs(sellingPrice - categoryPrice), 2); const wearLevel = getWearLevel(); // 仅差价 >1 时记录 if (diff <= 1) { log(`📉 差价 ≤1,不记录: ${diff}`); return false; } try { const file = new File(CSV_FILE_PATH); const needsHeader = !file.exists() || file.length() === 0; const writer = open(CSV_FILE_PATH, "a"); if (needsHeader) { writer.write("时间,物品名称,磨损程度,定价,售价,差价\n"); log("📊 创建CSV并写入表头"); } const escapedName = taskName.replace(/"/g, '""'); const line = [ new Date().toLocaleString(), `"${escapedName}"`, `"${wearLevel}"`, categoryPrice.toFixed(2), sellingPrice.toFixed(2), diff.toFixed(2) ].join(",") + "\n"; writer.write(line); writer.close(); successCount++; toastLog( `📌 ${taskName}\n` + `🔺 差额: ${diff}\n` + `📈 累计: ${successCount} 条` ); return true; } catch (e) { log("❌ 写入失败: " + e.message); return false; } } // ======== 4. 主循环 ========== while (true) { log("🔄 ========== 新一轮扫描开始 =========="); // A: 等待列表页 if (!waitForListPage()) { back(); sleep(2000); continue; } // D: 扫描并点击符合条件的商品(押金 >500) let clicked = false; const rv = id(LIST_PAGE_ID).findOne(2000); if (!rv) { log("❌ 未找到 RecyclerView"); continue; } const items = rv.children(); for (let i = 0; i < items.size(); i++) { const child = items.get(i); const depositWidget = child.findOne(id(DEPOSIT_ID)); if (!depositWidget) continue; const rawDeposit = depositWidget.text(); const deposit = extractNumber(rawDeposit); if (isNaN(deposit) || deposit <= 500) continue; const nameWidget = child.findOne(id(NAME_ID)); const itemName = (nameWidget?.text() || nameWidget?.desc() || `未命名-${i}`).trim(); const key = normalizeString(itemName) + "@" + Math.round(deposit * 100); if (processedKeys[key]) { log(`🔁 跳过已处理: ${itemName} | ¥${deposit}`); continue; } if (child.click()) { log(`✅ 成功点击: ${itemName} | 押金¥${deposit}`); processedKeys[key] = true; clicked = true; break; } else { log("❌ 点击失败"); } } // E: 无目标则滑动载 if (!clicked) { log("📭 无新目标,执行上滑"); if (swipeUp()) continue; toastLog("🔚 已到底部,脚本结束"); break; } // B: 图像识别操作 performImageClicks(); // C: 数据采集与记录 collectAndSaveData(); // 返回列表 back(); if (!waitForListPage()) { toastLog("⏳ 返回失败,脚本终止"); break; } sleep(1000); } ``` --- ### ✅ 使用说明 1. 保存为 `.js` 文件(如 `scan_and_compare.js`) 2. 确保模板图存在: - `/sdcard/脚本/小图/磨损区间.png` - `/sdcard/脚本/小图/磨损度.png` 3. 运行前授予截图权限 4. 进入商品列表页后启动脚本 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值