TwoFootBot-rust/.idea/copilotDiffState.xml

27 lines
25 KiB
XML
Raw Permalink Normal View History

2026-10-19 08:09:48 +00:00
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CopilotDiffPersistence">
<option name="pendingDiffs">
<map>
<entry key="/main (snapshot).rs">
<value>
<PendingDiffInfo>
<option name="filePath" value="/main (snapshot).rs" />
<option name="originalContent" value="mod policy;&#10;mod pingEsp32;&#10;mod command;&#10;&#10;use pingEsp32::Link;&#10;use std::time::Duration;&#10;&#10;fn main() -&gt; std::io::Result&lt;()&gt; {&#10; let mut link = Link::open_default()?;&#10; link.send_angles(&amp;[1.57;8])?;&#10;&#10; let mut cmd = command::spawn_listener();&#10;&#10; let mut i = 0;&#10; while i &gt; -1 {&#10; i += 1;&#10;&#10; if cmd.poll_from_terminal() {&#10; let state = cmd.load();&#10; let vec = command::state_to_vector(state);&#10; println!(&quot;[CommandState] {:?} (state=0b{:03b})&quot;, vec, state);&#10; }&#10;&#10; while let Some(msg) = link.recv_timeout(Duration::from_millis(20)) {&#10; if msg.is_data() {&#10; if let Some(mut obs) = msg.telemetry() {&#10; let state = cmd.load();&#10; let cmd_vec = command::state_to_vector(state);&#10; obs[6] = cmd_vec[0];&#10; obs[7] = cmd_vec[1];&#10; obs[8] = cmd_vec[2];&#10;&#10; println!(&quot;收到 36 维观测值(含指令): {:?}&quot;, obs);&#10; let action = policy::policy(obs).expect(&quot;TODO: panic message&quot;);&#10; link.send_angles(&amp;action)?;&#10; println!(&quot;[Action]:{:?}, 【{}】&quot;, action, i);&#10; }&#10; } else if msg.is_reply() {&#10; println!(&quot;[REPLY] {}&quot;, msg.text());&#10; } else {&#10; println!(&quot;[TEXT] {}&quot;, msg.text());&#10; }&#10; }&#10;&#10; std::thread::sleep(Duration::from_millis(5));&#10; }&#10;&#10; Ok(())&#10;}&#10;" />
<option name="updatedContent" value="mod policy;&#10;mod pingEsp32;&#10;mod command;&#10;&#10;use pingEsp32::Link;&#10;use std::time::Duration;&#10;&#10;fn main() -&gt; std::io::Result&lt;()&gt; {&#10; let mut link = Link::open_default()?;&#10; link.send_angles(&amp;[1.57;8])?;&#10;&#10; let mut cmd = command::spawn_listener();&#10;&#10; let mut i = 0;&#10; while i &gt; -1 {&#10; i += 1;&#10;&#10; if let Some(vec) = cmd.poll_from_terminal() {&#10; println!(&quot;[CommandState] {:?}&quot;, vec);&#10; if vec == [0.0, 0.0, 0.0] {&#10; println!(&quot;[Command] released -&gt; zero&quot;);&#10; }&#10; }&#10;&#10; while let Some(msg) = link.recv_timeout(Duration::from_millis(20)) {&#10; if msg.is_data() {&#10; if let Some(mut obs) = msg.telemetry() {&#10; let cmd_vec = cmd.current_vector();&#10; obs[6] = cmd_vec[0];&#10; obs[7] = cmd_vec[1];&#10; obs[8] = cmd_vec[2];&#10;&#10; println!(&quot;收到 36 维观测值(含指令): {:?}&quot;, obs);&#10; let action = policy::policy(obs).expect(&quot;TODO: panic message&quot;);&#10; link.send_angles(&amp;action)?;&#10; println!(&quot;[Action]:{:?}, 【{}】&quot;, action, i);&#10; }&#10; } else if msg.is_reply() {&#10; println!(&quot;[REPLY] {}&quot;, msg.text());&#10; } else {&#10; println!(&quot;[TEXT] {}&quot;, msg.text());&#10; }&#10; }&#10;&#10; std::thread::sleep(Duration::from_millis(5));&#10; }&#10;&#10; Ok(())&#10;}" />
</PendingDiffInfo>
</value>
</entry>
<entry key="/pingEsp32 (snapshot).rs">
<value>
<PendingDiffInfo>
<option name="filePath" value="/pingEsp32 (snapshot).rs" />
<option name="originalContent" value="use std::io::{BufRead, BufReader, Read, Write};&#10;use std::net::TcpStream;&#10;use std::sync::atomic::{AtomicBool, Ordering};&#10;use std::sync::mpsc::{self, Receiver, Sender, RecvTimeoutError};&#10;use std::sync::Arc;&#10;use std::thread::{self, JoinHandle};&#10;use std::time::Duration;&#10;&#10;use std::f32::consts::PI;&#10;&#10;pub const ESP32_IP: &amp;str = &quot;192.168.4.1&quot;;&#10;pub const ESP32_PORT: u16 = 3333;&#10;pub const NUM_SERVOS: usize = 8;&#10;&#10;const TELEMETRY_MAGIC: [u8; 2] = [0xA5, 0x5A];&#10;const TELEMETRY_FRAME_LEN: usize = 22;&#10;&#10;/// 从 ESP32 收到的一条消息(可包含 ASCII 文本,也可包含 36 维 IMU 数据)&#10;#[derive(Debug, Clone)]&#10;pub struct Esp32Message {&#10; text: String,&#10; telemetry: Option&lt;[f32; 36]&gt;,&#10;}&#10;&#10;impl Esp32Message {&#10; pub fn new_text(text: impl Into&lt;String&gt;) -&gt; Self {&#10; Self {&#10; text: text.into(),&#10; telemetry: None,&#10; }&#10; }&#10;&#10; pub fn new_telemetry(data: [f32; 36]) -&gt; Self {&#10; Self {&#10; text: &quot;IMU&quot;.to_string(),&#10; telemetry: Some(data),&#10; }&#10; }&#10;&#10; /// 是否是数据推送(二进制 IMU 帧)&#10; pub fn is_data(&amp;self) -&gt; bool { self.telemetry.is_some() }&#10;&#10; /// 是否是应答,比如 &quot;ESP32: OK ...&quot;&#10; pub fn is_reply(&amp;self) -&gt; bool {&#10; self.telemetry.is_none() &amp;&amp; self.text.starts_with(&quot;ESP32:&quot;)&#10; }&#10;&#10; pub fn text(&amp;self) -&gt; &amp;str { &amp;self.text }&#10;&#10; /// 返回 36 维 f32 数组;其余位置按 0.0 填充。&#10; pub fn telemetry(&amp;self) -&gt; Option&lt;[f32; 36]&gt; { self.telemetry }&#10;}&#10;&#10;// ==================== 双向连接 ====================&#10;&#10;pub struct Link {&#10; writer: TcpStream,&#10; rx: Receiver&lt;Esp32Message&gt;,&#10; stop: Arc&lt;AtomicBool&gt;,&#10; reader_job: Option&lt;JoinHandle&lt;()&gt;&gt;,&#10;}&#10;&#10;impl Link {&#10; /// 建立连接并启动后台接收线程&#10; pub fn open(ip: &amp;str, port: u16) -&gt; std::io::Result&lt;Self&gt; {&#10; let addr = format!(&quot;{}:{}&quot;, ip, port);&#10; println!(&quot;[*] 连接 {} ...&quot;, addr);&#10; println!(&quot;请连接上esp32的wifi热点后再运行本程序【ESP32_AP】&quot;);&#10; let stream = TcpStream::connect(&amp;addr)?;&#10; stream.set_nodelay(true)?;&#10; stream.set_read_timeout(Some(Duration::from_millis(200)))?;&#10; println!(&quot;[+] 已连接&quot;);&#10;&#10; let reader_stream = stream.try_clone()?;&#10; let (tx, rx): (Sender&lt;Esp32Message&gt;, Receiver&lt;Esp32Message&gt;) = mpsc::channel();&#10; let stop = Arc::new(AtomicBool::new(false));&#10;&#10; let reader_job = spawn_reader(reader_stream, tx, Arc::clone(&amp;stop));&#10;&#10; Ok(Self {&#10; writer: stream,&#10; rx,&#10; stop,&#10; reader_job: Some(reader_job),&#10; })&#10; }&#10;&#10; pub fn open_default() -&gt; std::io::Result&lt;Self&gt; {&#10; Self::open(ESP32_IP, ESP32_PORT)&#10; }&#10;&#10; // ---------- 发送 ----------&#10;&#10; /// 发送弧度列表&#10; pub fn send_angles(&amp;mut self, rads: &amp;[f32]) -&gt; std::io::Result&lt;()&gt; {&#10; let n = rads.len().min(NUM_SERVOS);&#10; let payload = rads[..n]&#10; .iter()&#10; .map(|r| format!(&quot;{:.4}&quot;, r.clamp(0.0, PI)))&#10; .collect::&lt;Vec&lt;_&gt;&gt;()&#10; .join(&quot;,&quot;);&#10; self.send_line(&amp;format!(&quot;RAD:{}&quot;, payload))&#10; }&#10;&#10; /// 发送角度列表&#10; pub fn send_degrees(&amp;mut self, degs: &amp;[f32]) -&gt; std::io::Result&lt;()&gt; {&#10; let n = degs.len().min(NUM_SERVOS);&#10; let payload = degs[..n]&#10; .iter()&#10; .map(|d| form
<option name="updatedContent" value="use std::io::{BufRead, BufReader, Read, Write};&#10;use std::net::TcpStream;&#10;use std::sync::atomic::{AtomicBool, Ordering};&#10;use std::sync::mpsc::{self, Receiver, Sender, RecvTimeoutError};&#10;use std::sync::Arc;&#10;use std::thread::{self, JoinHandle};&#10;use std::time::Duration;&#10;&#10;use std::f32::consts::PI;&#10;&#10;pub const ESP32_IP: &amp;str = &quot;192.168.4.1&quot;;&#10;pub const ESP32_PORT: u16 = 3333;&#10;pub const NUM_SERVOS: usize = 8;&#10;&#10;const TELEMETRY_MAGIC: [u8; 2] = [0xA5, 0x5A];&#10;const TELEMETRY_FRAME_LEN: usize = 22;&#10;&#10;/// 从 ESP32 收到的一条消息(可包含 ASCII 文本,也可包含 36 维 IMU 数据)&#10;#[derive(Debug, Clone)]&#10;pub struct Esp32Message {&#10; text: String,&#10; telemetry: Option&lt;[f32; 36]&gt;,&#10;}&#10;&#10;impl Esp32Message {&#10; pub fn new_text(text: impl Into&lt;String&gt;) -&gt; Self {&#10; Self {&#10; text: text.into(),&#10; telemetry: None,&#10; }&#10; }&#10;&#10; pub fn new_telemetry(data: [f32; 36]) -&gt; Self {&#10; Self {&#10; text: &quot;IMU&quot;.to_string(),&#10; telemetry: Some(data),&#10; }&#10; }&#10;&#10; /// 是否是数据推送(二进制 IMU 帧)&#10; pub fn is_data(&amp;self) -&gt; bool { self.telemetry.is_some() }&#10;&#10; /// 是否是应答,比如 &quot;ESP32: OK ...&quot;&#10; pub fn is_reply(&amp;self) -&gt; bool {&#10; self.telemetry.is_none() &amp;&amp; self.text.starts_with(&quot;ESP32:&quot;)&#10; }&#10;&#10; pub fn text(&amp;self) -&gt; &amp;str { &amp;self.text }&#10;&#10; /// 返回 36 维 f32 数组;其余位置按 0.0 填充。&#10; pub fn telemetry(&amp;self) -&gt; Option&lt;[f32; 36]&gt; { self.telemetry }&#10;}&#10;&#10;// ==================== 双向连接 ====================&#10;&#10;pub struct Link {&#10; writer: TcpStream,&#10; rx: Receiver&lt;Esp32Message&gt;,&#10; stop: Arc&lt;AtomicBool&gt;,&#10; reader_job: Option&lt;JoinHandle&lt;()&gt;&gt;,&#10;}&#10;&#10;impl Link {&#10; /// 建立连接并启动后台接收线程&#10; pub fn open(ip: &amp;str, port: u16) -&gt; std::io::Result&lt;Self&gt; {&#10; let addr = format!(&quot;{}:{}&quot;, ip, port);&#10; println!(&quot;[*] 连接 {} ...&quot;, addr);&#10; println!(&quot;请连接上esp32的wifi热点后再运行本程序【ESP32_AP】&quot;);&#10; let stream = TcpStream::connect(&amp;addr)?;&#10; stream.set_nodelay(true)?;&#10; stream.set_read_timeout(Some(Duration::from_millis(200)))?;&#10; println!(&quot;[+] 已连接&quot;);&#10;&#10; let reader_stream = stream.try_clone()?;&#10; let (tx, rx): (Sender&lt;Esp32Message&gt;, Receiver&lt;Esp32Message&gt;) = mpsc::channel();&#10; let stop = Arc::new(AtomicBool::new(false));&#10;&#10; let reader_job = spawn_reader(reader_stream, tx, Arc::clone(&amp;stop));&#10;&#10; Ok(Self {&#10; writer: stream,&#10; rx,&#10; stop,&#10; reader_job: Some(reader_job),&#10; })&#10; }&#10;&#10; pub fn open_default() -&gt; std::io::Result&lt;Self&gt; {&#10; Self::open(ESP32_IP, ESP32_PORT)&#10; }&#10;&#10; // ---------- 发送 ----------&#10;&#10; /// 发送弧度列表&#10; pub fn send_angles(&amp;mut self, rads: &amp;[f32]) -&gt; std::io::Result&lt;()&gt; {&#10; let n = rads.len().min(NUM_SERVOS);&#10; let payload = rads[..n]&#10; .iter()&#10; .map(|r| format!(&quot;{:.4}&quot;, r.clamp(0.0, PI)))&#10; .collect::&lt;Vec&lt;_&gt;&gt;()&#10; .join(&quot;,&quot;);&#10; self.send_line(&amp;format!(&quot;RAD:{}&quot;, payload))&#10; }&#10;&#10; /// 发送角度列表&#10; pub fn send_degrees(&amp;mut self, degs: &amp;[f32]) -&gt; std::io::Result&lt;()&gt; {&#10; let n = degs.len().min(NUM_SERVOS);&#10; let payload = degs[..n]&#10; .iter()&#10; .map(|d| forma
</PendingDiffInfo>
</value>
</entry>
</map>
</option>
</component>
</project>