Hugo.V commited on
Commit
a972f11
·
1 Parent(s): 81288b1

url ytb creation de sequence et main commenté

Browse files
jericho/main.py CHANGED
@@ -898,6 +898,8 @@ class Jericho(ReachyMiniApp): # appli principale serveur app backend
898
  angle = (0.5 + oscillation) * ANTENNA_MAX_alt
899
  left_ant = -angle
900
  right_ant = angle
 
 
901
  elif emotion == "CONTENT":
902
  oscillation = 0.8 * math.sin(2 * math.pi * 0.5 * t_state)
903
  angle = oscillation * ANTENNA_MAX_alt
@@ -911,11 +913,11 @@ class Jericho(ReachyMiniApp): # appli principale serveur app backend
911
  left_ant = target - 0.2
912
  right_ant = -(target - 0.2)
913
  elif emotion == "PEUR":
914
- tremblement = 0.1 * math.sin(2 * math.pi * 15.0 * t_state)
915
  angle = -1.0 * (1.0 - math.exp(-1.5 * t_state) + tremblement) * ANTENNA_MAX
916
  left_ant = angle - 0.2
917
  right_ant = -(angle - 0.2)
918
- else:
919
  angle = 1.0 * (1.0 - math.exp(-14.0 * t_state)) * ANTENNA_MAX_alt
920
  left_ant = -(angle - 0.3)
921
  right_ant = (angle - 0.3)
 
898
  angle = (0.5 + oscillation) * ANTENNA_MAX_alt
899
  left_ant = -angle
900
  right_ant = angle
901
+
902
+
903
  elif emotion == "CONTENT":
904
  oscillation = 0.8 * math.sin(2 * math.pi * 0.5 * t_state)
905
  angle = oscillation * ANTENNA_MAX_alt
 
913
  left_ant = target - 0.2
914
  right_ant = -(target - 0.2)
915
  elif emotion == "PEUR":
916
+ tremblement = 0.1 * math.sin(2 * math.pi * 16.0 * t_state)
917
  angle = -1.0 * (1.0 - math.exp(-1.5 * t_state) + tremblement) * ANTENNA_MAX
918
  left_ant = angle - 0.2
919
  right_ant = -(angle - 0.2)
920
+ elif emotion =="JOIE":
921
  angle = 1.0 * (1.0 - math.exp(-14.0 * t_state)) * ANTENNA_MAX_alt
922
  left_ant = -(angle - 0.3)
923
  right_ant = (angle - 0.3)
jericho/static/index.html CHANGED
@@ -10,15 +10,11 @@
10
  <header>
11
  <h1>【⚙】Jericho projet : Reachy Mini【⚙】</h1>
12
  <div id="conteneurHeader">
13
- <<<<<<< HEAD
14
  <img
15
  src="static/images/logoReachyMini.png"
16
  alt="Photo de Reachy"
17
  width="10%"
18
  />
19
- =======
20
- <img src="static/images/logoReachyMini.png" alt="Photo de Reachy" width="10%" />
21
- >>>>>>> abc461f5bd956c99158acc406f426086d1d49797
22
  <div id="robot-status">Prêt</div>
23
  </div>
24
  </header>
@@ -49,7 +45,6 @@
49
  </section>
50
 
51
  <section class="card">
52
- <<<<<<< HEAD
53
  <h2>[▶] Importer depuis YouTube</h2>
54
  <div class="form-group">
55
  <label>Nom du projet :</label>
@@ -74,22 +69,19 @@
74
  </section>
75
 
76
  <section class="card">
77
- =======
78
- >>>>>>> abc461f5bd956c99158acc406f426086d1d49797
79
  <h2>►► Votre bibliothèque</h2>
80
  <div id="video-library" class="grid-library">
81
  <p class="empty-text">Aucune vidéo enregistrée.</p>
82
  </div>
83
  </section>
 
84
  <section class="card">
85
  <h2>[+] Créer une séquence d'émotions</h2>
86
  <div class="form-group">
87
  <label>Nom de la création :</label>
88
  <input type="text" id="seq-name" placeholder="ex: sequence_test_01" />
89
  </div>
90
-
91
  <div id="sequence-list" style="margin-bottom: 15px"></div>
92
-
93
  <button
94
  id="add-emotion-btn"
95
  class="btn-primary"
@@ -106,19 +98,16 @@
106
  </button>
107
  <p id="seq-msg"></p>
108
  </section>
 
109
  <section id="player-section" class="card hidden">
110
  <h2 id="current-video-title">Lecture</h2>
111
  <video id="video-player" controls></video>
112
-
113
  <div class="sync-controls">
114
  <button id="launch-sync-btn" class="btn-success">
115
  [►] Lire vidéo + robot synchronisés
116
- <<<<<<< HEAD
117
  </button>
118
  <button id="launch-seq-btn" class="btn-success" style="display: none">
119
  [►] Lire la séquence (sans vidéo)
120
- =======
121
- >>>>>>> abc461f5bd956c99158acc406f426086d1d49797
122
  </button>
123
  <p class="sync-hint">
124
  Les pauses, reprises et déplacements dans la vidéo sont envoyés au
@@ -130,7 +119,6 @@
130
  <section class="card">
131
  <h2>☻ Les émotions</h2>
132
  <div id="listeEmotions">
133
- <<<<<<< HEAD
134
  <button id="joie">Joie</button>
135
  <button id="content">Content</button>
136
  <button id="surprise">Surprise</button>
@@ -138,29 +126,6 @@
138
  <button id="peur">Peur</button>
139
  <button id="tristesse">Tristesse</button>
140
  <button id="neutre">Neutre</button>
141
- =======
142
- <button id="joie">
143
- Joie
144
- </button>
145
- <button id="content">
146
- Content
147
- </button>
148
- <button id="surprise">
149
- Surprise
150
- </button>
151
- <button id="colere">
152
- Colère
153
- </button>
154
- <button id="peur">
155
- Peur
156
- </button>
157
- <button id="tristesse">
158
- Tristesse
159
- </button>
160
- <button id="neutre">
161
- Neutre
162
- </button>
163
- >>>>>>> abc461f5bd956c99158acc406f426086d1d49797
164
  </div>
165
  </section>
166
  </main>
 
10
  <header>
11
  <h1>【⚙】Jericho projet : Reachy Mini【⚙】</h1>
12
  <div id="conteneurHeader">
 
13
  <img
14
  src="static/images/logoReachyMini.png"
15
  alt="Photo de Reachy"
16
  width="10%"
17
  />
 
 
 
18
  <div id="robot-status">Prêt</div>
19
  </div>
20
  </header>
 
45
  </section>
46
 
47
  <section class="card">
 
48
  <h2>[▶] Importer depuis YouTube</h2>
49
  <div class="form-group">
50
  <label>Nom du projet :</label>
 
69
  </section>
70
 
71
  <section class="card">
 
 
72
  <h2>►► Votre bibliothèque</h2>
73
  <div id="video-library" class="grid-library">
74
  <p class="empty-text">Aucune vidéo enregistrée.</p>
75
  </div>
76
  </section>
77
+
78
  <section class="card">
79
  <h2>[+] Créer une séquence d'émotions</h2>
80
  <div class="form-group">
81
  <label>Nom de la création :</label>
82
  <input type="text" id="seq-name" placeholder="ex: sequence_test_01" />
83
  </div>
 
84
  <div id="sequence-list" style="margin-bottom: 15px"></div>
 
85
  <button
86
  id="add-emotion-btn"
87
  class="btn-primary"
 
98
  </button>
99
  <p id="seq-msg"></p>
100
  </section>
101
+
102
  <section id="player-section" class="card hidden">
103
  <h2 id="current-video-title">Lecture</h2>
104
  <video id="video-player" controls></video>
 
105
  <div class="sync-controls">
106
  <button id="launch-sync-btn" class="btn-success">
107
  [►] Lire vidéo + robot synchronisés
 
108
  </button>
109
  <button id="launch-seq-btn" class="btn-success" style="display: none">
110
  [►] Lire la séquence (sans vidéo)
 
 
111
  </button>
112
  <p class="sync-hint">
113
  Les pauses, reprises et déplacements dans la vidéo sont envoyés au
 
119
  <section class="card">
120
  <h2>☻ Les émotions</h2>
121
  <div id="listeEmotions">
 
122
  <button id="joie">Joie</button>
123
  <button id="content">Content</button>
124
  <button id="surprise">Surprise</button>
 
126
  <button id="peur">Peur</button>
127
  <button id="tristesse">Tristesse</button>
128
  <button id="neutre">Neutre</button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  </div>
130
  </section>
131
  </main>
jericho/static/main.js CHANGED
@@ -74,13 +74,11 @@ document.addEventListener('DOMContentLoaded', () => {
74
  };
75
  }
76
 
77
- // Boutons d'émotions
78
  const emotionIds = ['joie', 'content', 'surprise', 'colere', 'peur', 'tristesse', 'neutre'];
79
  emotionIds.forEach(id => {
80
  const el = document.getElementById(id);
81
  if (!el) return;
82
  el.addEventListener('click', async () => {
83
- // Highlight du bouton actif
84
  emotionIds.forEach(eid => document.getElementById(eid)?.classList.remove('active-emotion'));
85
  el.classList.add('active-emotion');
86
 
@@ -236,7 +234,6 @@ async function loadLibrary() {
236
  <br><strong>${safeName}</strong><br><span style="color:green; font-size:12px;">Prêt</span>
237
  </div>`;
238
  } else if (video.status === 'CREATION_DONE') {
239
-
240
  const nameArg = JSON.stringify(video.name).replaceAll('"', '&quot;');
241
  newHTML += `<div class="video-item" onclick="loadVideoPlayer(${nameArg}, null)" style="position:relative; border: 2px solid purple;">
242
  ${deleteBtn}
@@ -262,7 +259,8 @@ async function loadLibrary() {
262
  ${deleteBtn}
263
  <br><strong>${safeName}</strong><br><span style="color:red; font-size:11px;">Échec (survolez)</span>
264
  </div>`;
265
- newHTML += `<div class="video-item" style="position:relative; opacity: 0.5; cursor: wait;">
 
266
  ${deleteBtn}
267
  <br><strong>${safeName}</strong><br><span style="color:gray; font-size:12px;">En attente</span>
268
  </div>`;
@@ -282,7 +280,6 @@ window.loadVideoPlayer = async function(name, url) {
282
  if (currentLoadedProject && currentLoadedProject !== name) {
283
  await sendPlayback('stop', { projectName: currentLoadedProject, playing: false });
284
  }
285
-
286
 
287
  document.querySelectorAll('#listeEmotions button').forEach(b => b.classList.remove('active-emotion'));
288
  await fetch('/api/emotion', {
@@ -299,7 +296,6 @@ window.loadVideoPlayer = async function(name, url) {
299
  const btnSeq = document.getElementById('launch-seq-btn');
300
 
301
  if (url) {
302
-
303
  videoPlayer.src = url;
304
  videoPlayer.style.display = 'block';
305
  if(btnSync) btnSync.style.display = 'inline-block';
@@ -307,7 +303,6 @@ window.loadVideoPlayer = async function(name, url) {
307
  videoPlayer.load();
308
  robotStatus.textContent = 'Vidéo chargée — son sur Reachy Mini';
309
  } else {
310
-
311
  videoPlayer.removeAttribute('src');
312
  videoPlayer.style.display = 'none';
313
  if(btnSync) btnSync.style.display = 'none';
@@ -318,7 +313,6 @@ window.loadVideoPlayer = async function(name, url) {
318
 
319
  videoPlayer.addEventListener('play', () => {
320
  if (!currentLoadedProject) return;
321
- videoPlayer.muted = true;
322
  robotStatus.textContent = 'Lecture synchronisée — audio robot';
323
  sendPlayback('play', { playing: true });
324
  startSyncLoop();
@@ -357,98 +351,6 @@ videoPlayer.addEventListener('ended', () => {
357
  stopSyncLoop();
358
  });
359
 
360
- let boutonJoie=document.getElementById('joie');
361
- let boutonContent=document.getElementById('content');
362
- let boutonSurprise=document.getElementById('surprise');
363
- let boutonColere=document.getElementById('colere');
364
- let boutonPeur=document.getElementById('peur');
365
- let boutonTristesse=document.getElementById('tristesse');
366
- let boutonNeutre=document.getElementById('neutre');
367
-
368
- boutonJoie.addEventListener("click", async () => {
369
- document.querySelectorAll('#listeEmotions button').forEach(b => b.classList.remove('active-emotion'));
370
- boutonJoie.classList.add('active-emotion');
371
-
372
- await fetch('/api/emotion', {
373
- method: 'POST',
374
- headers: { 'Content-Type': 'application/json' },
375
- body: JSON.stringify({ emotion: 'JOIE' })
376
- });
377
- robotStatus.textContent = 'Émotion : Joie';
378
- });
379
-
380
- boutonContent.addEventListener("click", async () => {
381
- document.querySelectorAll('#listeEmotions button').forEach(b => b.classList.remove('active-emotion'));
382
- boutonJoie.classList.add('active-emotion');
383
-
384
- await fetch('/api/emotion', {
385
- method: 'POST',
386
- headers: { 'Content-Type': 'application/json' },
387
- body: JSON.stringify({ emotion: 'CONTENT' })
388
- });
389
- robotStatus.textContent = 'Émotion : Content';
390
- });
391
-
392
- boutonSurprise.addEventListener("click", async () => {
393
- document.querySelectorAll('#listeEmotions button').forEach(b => b.classList.remove('active-emotion'));
394
- boutonJoie.classList.add('active-emotion');
395
-
396
- await fetch('/api/emotion', {
397
- method: 'POST',
398
- headers: { 'Content-Type': 'application/json' },
399
- body: JSON.stringify({ emotion: 'SURPRISE' })
400
- });
401
- robotStatus.textContent = 'Émotion : Surprise';
402
- });
403
-
404
- boutonColere.addEventListener("click", async () => {
405
- document.querySelectorAll('#listeEmotions button').forEach(b => b.classList.remove('active-emotion'));
406
- boutonJoie.classList.add('active-emotion');
407
-
408
- await fetch('/api/emotion', {
409
- method: 'POST',
410
- headers: { 'Content-Type': 'application/json' },
411
- body: JSON.stringify({ emotion: 'COLERE' })
412
- });
413
- robotStatus.textContent = 'Émotion : Colère';
414
- });
415
-
416
- boutonPeur.addEventListener("click", async () => {
417
- document.querySelectorAll('#listeEmotions button').forEach(b => b.classList.remove('active-emotion'));
418
- boutonJoie.classList.add('active-emotion');
419
-
420
- await fetch('/api/emotion', {
421
- method: 'POST',
422
- headers: { 'Content-Type': 'application/json' },
423
- body: JSON.stringify({ emotion: 'PEUR' })
424
- });
425
- robotStatus.textContent = 'Émotion : Peur';
426
- });
427
-
428
- boutonTristesse.addEventListener("click", async () => {
429
- document.querySelectorAll('#listeEmotions button').forEach(b => b.classList.remove('active-emotion'));
430
- boutonJoie.classList.add('active-emotion');
431
-
432
- await fetch('/api/emotion', {
433
- method: 'POST',
434
- headers: { 'Content-Type': 'application/json' },
435
- body: JSON.stringify({ emotion: 'TRISTESSE' })
436
- });
437
- robotStatus.textContent = 'Émotion : Tristesse';
438
- });
439
-
440
- boutonNeutre.addEventListener("click", async () => {
441
- document.querySelectorAll('#listeEmotions button').forEach(b => b.classList.remove('active-emotion'));
442
- boutonJoie.classList.add('active-emotion');
443
-
444
- await fetch('/api/emotion', {
445
- method: 'POST',
446
- headers: { 'Content-Type': 'application/json' },
447
- body: JSON.stringify({ emotion: 'NEUTRE' })
448
- });
449
- robotStatus.textContent = 'Émotion : Neutre';
450
- });
451
-
452
  function createEmotionRow() {
453
  const row = document.createElement('div');
454
  row.className = 'emotion-row';
@@ -494,7 +396,6 @@ function createEmotionRow() {
494
  document.getElementById('sequence-list').appendChild(row);
495
  }
496
 
497
- // Ajouter une ligne par défaut au chargement
498
  document.addEventListener('DOMContentLoaded', () => {
499
  const addEmotionBtn = document.getElementById('add-emotion-btn');
500
  if(addEmotionBtn) {
@@ -502,7 +403,6 @@ document.addEventListener('DOMContentLoaded', () => {
502
  createEmotionRow();
503
  }
504
 
505
- // Configurer le bouton Play de la séquence
506
  const playSeqBtn = document.getElementById('launch-seq-btn');
507
  if(playSeqBtn) {
508
  playSeqBtn.onclick = () => {
@@ -553,8 +453,8 @@ document.getElementById('save-seq-btn').onclick = async function() {
553
  msg.style.color = 'green';
554
  document.getElementById('seq-name').value = '';
555
  document.getElementById('sequence-list').innerHTML = '';
556
- createEmotionRow(); // Reset l'interface
557
- loadLibrary(); // Met à jour la liste
558
  } else {
559
  const result = await response.json();
560
  msg.textContent = `Erreur : ${result.detail}`;
@@ -564,4 +464,4 @@ document.getElementById('save-seq-btn').onclick = async function() {
564
  msg.textContent = 'Erreur réseau.';
565
  msg.style.color = 'red';
566
  }
567
- };
 
74
  };
75
  }
76
 
 
77
  const emotionIds = ['joie', 'content', 'surprise', 'colere', 'peur', 'tristesse', 'neutre'];
78
  emotionIds.forEach(id => {
79
  const el = document.getElementById(id);
80
  if (!el) return;
81
  el.addEventListener('click', async () => {
 
82
  emotionIds.forEach(eid => document.getElementById(eid)?.classList.remove('active-emotion'));
83
  el.classList.add('active-emotion');
84
 
 
234
  <br><strong>${safeName}</strong><br><span style="color:green; font-size:12px;">Prêt</span>
235
  </div>`;
236
  } else if (video.status === 'CREATION_DONE') {
 
237
  const nameArg = JSON.stringify(video.name).replaceAll('"', '&quot;');
238
  newHTML += `<div class="video-item" onclick="loadVideoPlayer(${nameArg}, null)" style="position:relative; border: 2px solid purple;">
239
  ${deleteBtn}
 
259
  ${deleteBtn}
260
  <br><strong>${safeName}</strong><br><span style="color:red; font-size:11px;">Échec (survolez)</span>
261
  </div>`;
262
+ } else {
263
+ newHTML += `<div class="video-item" style="position:relative; opacity: 0.5; cursor: wait;">
264
  ${deleteBtn}
265
  <br><strong>${safeName}</strong><br><span style="color:gray; font-size:12px;">En attente</span>
266
  </div>`;
 
280
  if (currentLoadedProject && currentLoadedProject !== name) {
281
  await sendPlayback('stop', { projectName: currentLoadedProject, playing: false });
282
  }
 
283
 
284
  document.querySelectorAll('#listeEmotions button').forEach(b => b.classList.remove('active-emotion'));
285
  await fetch('/api/emotion', {
 
296
  const btnSeq = document.getElementById('launch-seq-btn');
297
 
298
  if (url) {
 
299
  videoPlayer.src = url;
300
  videoPlayer.style.display = 'block';
301
  if(btnSync) btnSync.style.display = 'inline-block';
 
303
  videoPlayer.load();
304
  robotStatus.textContent = 'Vidéo chargée — son sur Reachy Mini';
305
  } else {
 
306
  videoPlayer.removeAttribute('src');
307
  videoPlayer.style.display = 'none';
308
  if(btnSync) btnSync.style.display = 'none';
 
313
 
314
  videoPlayer.addEventListener('play', () => {
315
  if (!currentLoadedProject) return;
 
316
  robotStatus.textContent = 'Lecture synchronisée — audio robot';
317
  sendPlayback('play', { playing: true });
318
  startSyncLoop();
 
351
  stopSyncLoop();
352
  });
353
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
354
  function createEmotionRow() {
355
  const row = document.createElement('div');
356
  row.className = 'emotion-row';
 
396
  document.getElementById('sequence-list').appendChild(row);
397
  }
398
 
 
399
  document.addEventListener('DOMContentLoaded', () => {
400
  const addEmotionBtn = document.getElementById('add-emotion-btn');
401
  if(addEmotionBtn) {
 
403
  createEmotionRow();
404
  }
405
 
 
406
  const playSeqBtn = document.getElementById('launch-seq-btn');
407
  if(playSeqBtn) {
408
  playSeqBtn.onclick = () => {
 
453
  msg.style.color = 'green';
454
  document.getElementById('seq-name').value = '';
455
  document.getElementById('sequence-list').innerHTML = '';
456
+ createEmotionRow();
457
+ loadLibrary();
458
  } else {
459
  const result = await response.json();
460
  msg.textContent = `Erreur : ${result.detail}`;
 
464
  msg.textContent = 'Erreur réseau.';
465
  msg.style.color = 'red';
466
  }
467
+ };