diff --git a/.gitignore b/.gitignore index dcab291..ce2cd0e 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ packages /Cs_HMI/Data/*.agvmap /Cs_HMI/AGVLogic/AGVMapEditor/Data/*.agvmap /Document/~$PICkit 프로그램 다운로드 매뉴얼.pptx +/HMI/TestProject/tts/assets diff --git a/Document/AGV_Charging_Sequence.md b/Document/AGV_Charging_Sequence.md new file mode 100644 index 0000000..eb41542 --- /dev/null +++ b/Document/AGV_Charging_Sequence.md @@ -0,0 +1,57 @@ +# AGV Charging Sequence Diagram + +이 문서는 `_SM_RUN_CHARGE_ON`, `_SM_RUN_CHARGE_OFF`, `_SM_RUN_CHARGE_CHECK` 소스 코드 분석을 바탕으로 작성되었습니다. + +## 1. 충전 시작 시퀀스 (Charge ON) + +AGV가 충전기 위치(RFID)에 정지해 있고, 정밀 정차용 마크 센서가 감지된 상태에서 수행됩니다. + +```mermaid +sequenceDiagram + participant AGV + participant Charger as Battery Charger + participant Sensors + participant ACS as ACS/Server + + Note over AGV: [조건 확인] 현재 위치 == 충전기 RFID & Mark Sensor ON + + AGV->>ACS: 충전 시작 명령 전송 (AGVCharge ON) + ACS->>Charger: 충전 활성화 + Charger-->>AGV: ACK (응답: "CBT") + + loop 충전 상태 확인 + AGV->>Sensors: Battery_charging 상태 체크 + Sensors-->>AGV: charging = true + end + + Note over AGV: 충전 수행 중 +``` + +## 2. 충전 해제 시퀀스 (Charge OFF) + +충전 작업을 종료하고 다음 작업으로 복귀하기 위해 수행됩니다. 급격한 상태 변화를 방지하기 위해 쿨다운 시간이 포함되어 있습니다. + +```mermaid +sequenceDiagram + participant AGV + participant Charger as Battery Charger + participant Sensors + participant ACS as ACS/Server + + AGV->>ACS: 충전 해제 전송 (AGVCharge OFF) + ACS->>Charger: 충전 비활성화 + + loop 해제 확인 + AGV->>Sensors: Battery_charging 상태 체크 + Sensors-->>AGV: charging = false + end + + Note over AGV: 5초 Cooldown 대기 (상태 안정화) + + AGV->>AGV: FLAG_CHARGEONA = false (최종 해제) + Note over AGV: 충전 해제 완료 +``` + +## 3. 관련 체크 로직 (Charge Check) +- **자동 해제**: 모든 작업(`_SM_RUN_BUFFER_IN`, `_SM_RUN_ENTER`, `_SM_RUN_EXIT` 등) 시작 시 가장 먼저 `_SM_RUN_CHARGE_OFF`를 호출하여 충전이 해제된 상태인지 보장합니다. +- **예외 처리**: 충전 명령 후 3초 이내에 응답(`ACK`)이 없으면 최대 5회까지 재전송을 시도합니다. 1분 이상 해제되지 않을 경우 `IDLE` 상태로 강제 전환됩니다. diff --git a/Document/AGV_Interaction_Sequence.md b/Document/AGV_Interaction_Sequence.md new file mode 100644 index 0000000..04837f6 --- /dev/null +++ b/Document/AGV_Interaction_Sequence.md @@ -0,0 +1,100 @@ +# AGV Interaction Sequence Diagram + +이 문서는 소스 코드 분석을 바탕으로 AGV의 버퍼 및 설비(Loader, Cleaner, Unloader) 진출입 시퀀스를 AGV 관점에서 정리한 것입니다. + +## 1. AGV 진입 시퀀스 (Entry/In) + +버퍼는 경로 복귀를 위한 180도 회전(`Turn`) 과정이 포함되어 있으며, 설비(Loader, Cleaner, Unloader)는 직선 이동 위주로 구성됩니다. + +```mermaid +sequenceDiagram + participant AGV + participant Sensors + participant ACS as ACS/Server + participant Equip as Equipment/Buffer + + Note over AGV: [조건 확인] 충전 OFF & 기구물 간섭 확인 + + rect rgb(240, 240, 240) + Note right of AGV: 버퍼 진입 (Buffer In) + AGV->>Sensors: Lidar OFF (안전 센서 일시 중지) + AGV->>AGV: Stop + AGV->>AGV: Left 180 Turn (방향 전환) + AGV->>AGV: Lift DOWN + alt PickOffEnter (카트 반납 시) + AGV->>AGV: Magnet ON + end + AGV->>Equip: 후진 진입 (Backward Low Speed) + Equip->>Sensors: Mark Sensor 감지 + AGV->>AGV: MarkStop (정밀 정지) + alt PickOffEnter (카트 반납 시) + AGV->>AGV: Magnet OFF + end + Note over AGV: 진입 완료 + end + + rect rgb(220, 230, 240) + Note right of AGV: 일반 설비 진입 (Loader, Cleaner, Unloader Enter) + AGV->>Sensors: Mark Sensor 유효성 확인 + AGV->>AGV: Lift DOWN + alt PickOffEnter (카트 반납 시) + AGV->>AGV: Magnet ON + end + AGV->>Equip: 후진 진입 (Backward Low Speed) + Equip->>Sensors: Mark Sensor 감지 + AGV->>AGV: MarkStop (정밀 정지) + alt PickOffEnter (카트 반납 시) + AGV->>AGV: Magnet OFF + end + Note over AGV: 진입 완료 + end +``` + +--- + +## 2. AGV 진출 시퀀스 (Exit/Out) + +진출 시에도 버퍼는 경로 복귀를 위한 180도 우회전(`Right Turn`)이 포함됩니다. + +```mermaid +sequenceDiagram + participant AGV + participant Sensors + participant ACS as ACS/Server + participant Equip as Equipment/Buffer + + Note over AGV: [조건 확인] 충전 OFF + + rect rgb(240, 240, 240) + Note right of AGV: 버퍼 진출 (Buffer Out) + alt PickOnExit (카트 수거 시) + AGV->>AGV: Lift UP + else PickOffExit (빈 차 복귀 시) + AGV->>AGV: Lift DOWN + end + AGV->>Equip: 전진 진출 (Forward Low Speed) + Equip->>Sensors: Mark Sensor 감지 (진출 지점) + AGV->>AGV: MarkStop & Stop + AGV->>AGV: Right 180 Turn (경로 복귀) + AGV->>Sensors: Lidar ON (안전 센서 활성화) + Note over AGV: 진출 완료 + end + + rect rgb(220, 230, 240) + Note right of AGV: 일반 설비 진출 (Loader, Cleaner, Unloader Exit) + alt PickOnExit (카트 수거 시) + AGV->>AGV: Lift UP + else PickOffExit (공차 이탈 시) + AGV->>AGV: Lift DOWN + end + AGV->>Equip: 전진 진출 (Forward Low Speed) + Equip->>Sensors: Mark Sensor 감지 (진출 지점) + AGV->>AGV: MarkStop & Stop + Note over AGV: 진출 완료 + end +``` + +## 3. 주요 차이점 요약 +- **Buffer**: 진입 시 `Left 180 Turn`, 진출 시 `Right 180 Turn`을 통해 방향을 반전시켜 작업 후 원래 경로로 복귀합니다. +- **Equipment**: 별도의 회전 없이 `Backward` 진입, `Forward` 진출을 수행합니다. +- **Common**: 진입 시에는 항상 리프트를 내린 상태(`Lift DN`)를 유지하며, 설비 내부에서의 정밀 정지는 `Mark Sensor`와 `MarkStop` 명령을 조합하여 수행합니다. diff --git a/HMI/TestProject/tts/Helper.cs b/HMI/TestProject/tts/Helper.cs index d13293b..06abbba 100644 --- a/HMI/TestProject/tts/Helper.cs +++ b/HMI/TestProject/tts/Helper.cs @@ -449,7 +449,7 @@ namespace Supertonic.WinForms } - public (float[] wav, float[] duration) Call(string text, string lang, Style style, int totalStep, float speed = 1.05f, float silenceDuration = 0.3f) + public (float[] wav, float[] duration) Call(string text, string lang, Style style, int totalStep, float speed = 1.05f, float silenceDuration = 0.3f, float initialSilenceDuration = 0.5f) { if (style.TtlShape[0] != 1) { @@ -461,14 +461,22 @@ namespace Supertonic.WinForms var wavCat = new List(); float durCat = 0.0f; + // Add initial silence to prevent cutting off the start of the audio + if (initialSilenceDuration > 0) + { + int initialSilenceLen = (int)(initialSilenceDuration * SampleRate); + wavCat.AddRange(new float[initialSilenceLen]); + durCat += initialSilenceDuration; + } + foreach (var chunk in textList) { var (wav, duration) = _Infer(new List { chunk }, new List { lang }, style, totalStep, speed); - if (wavCat.Count == 0) + if (wavCat.Count == 0 || (wavCat.Count == (int)(initialSilenceDuration * SampleRate) && initialSilenceDuration > 0)) { wavCat.AddRange(wav); - durCat = duration[0]; + durCat += duration[0]; } else { @@ -762,7 +770,24 @@ namespace Supertonic.WinForms } } - + + } + + public static void PlayWavFile(string filename) + { + if (!File.Exists(filename)) return; + + try + { + using (var player = new System.Media.SoundPlayer(filename)) + { + player.Play(); + } + } + catch (Exception ex) + { + Console.WriteLine($"Error playing WAV file: {ex.Message}"); + } } // ============================================================================ diff --git a/HMI/TestProject/tts/fMain.cs b/HMI/TestProject/tts/fMain.cs index b14c7d2..25d9990 100644 --- a/HMI/TestProject/tts/fMain.cs +++ b/HMI/TestProject/tts/fMain.cs @@ -55,6 +55,9 @@ namespace Supertonic.WinForms Helper.WriteWavFile(outputPath, result.wav, _tts.SampleRate); Log($"Saved: {outputPath}"); + // Play the generated WAV file immediately + Helper.PlayWavFile(outputPath); + MessageBox.Show($"Synthesis completed successfully!\nSaved to: {outputPath}"); } catch (Exception ex)