Commit
•
fb118db
1
Parent(s):
09a6f7f
Policies are now loaded from the hub
Browse files- js/draw_p5js.js +2 -2
- js/envs/multi_agents_continuous_parkour.js +1 -2
- js/ui_state/components/agents_list.js +1 -2
- js/ui_state/components/morphologies_list.js +5 -10
- js/ui_state/store/actions.js +0 -1
- js/ui_state/store/mutations.js +2 -3
- ui.js +30 -10
js/draw_p5js.js
CHANGED
@@ -225,8 +225,8 @@ function drawName(agent, scale){
|
|
225 |
else if(agent.morphology == "fish"){
|
226 |
y_pos = pos.y + agent.agent_body.AGENT_HEIGHT * 2;
|
227 |
}
|
228 |
-
|
229 |
-
text(agent.name
|
230 |
}
|
231 |
|
232 |
/**
|
|
|
225 |
else if(agent.morphology == "fish"){
|
226 |
y_pos = pos.y + agent.agent_body.AGENT_HEIGHT * 2;
|
227 |
}
|
228 |
+
|
229 |
+
text(agent.name, x_pos, RENDERING_VIEWER_H - y_pos);
|
230 |
}
|
231 |
|
232 |
/**
|
js/envs/multi_agents_continuous_parkour.js
CHANGED
@@ -91,7 +91,7 @@ class MultiAgentsContinuousParkour {
|
|
91 |
/**
|
92 |
* Creates an agent with the given parameters.
|
93 |
* @param morphology {string} - Name of the morphology
|
94 |
-
* @param policy {{name: string
|
95 |
* @param init_pos {{x: number, y: number}} - Initial position of the agent
|
96 |
*/
|
97 |
create_agent(morphology, policy, init_pos){
|
@@ -99,7 +99,6 @@ class MultiAgentsContinuousParkour {
|
|
99 |
let agent = {
|
100 |
id: this.agents.length,
|
101 |
name: policy.name,
|
102 |
-
age: policy.age,
|
103 |
is_selected: false,
|
104 |
morphology: morphology,
|
105 |
policy: policy,
|
|
|
91 |
/**
|
92 |
* Creates an agent with the given parameters.
|
93 |
* @param morphology {string} - Name of the morphology
|
94 |
+
* @param policy {{name: string path: string}} - Name and path of the policy model
|
95 |
* @param init_pos {{x: number, y: number}} - Initial position of the agent
|
96 |
*/
|
97 |
create_agent(morphology, policy, init_pos){
|
|
|
99 |
let agent = {
|
100 |
id: this.agents.length,
|
101 |
name: policy.name,
|
|
|
102 |
is_selected: false,
|
103 |
morphology: morphology,
|
104 |
policy: policy,
|
js/ui_state/components/agents_list.js
CHANGED
@@ -23,7 +23,6 @@ export default class AgentsList extends Component {
|
|
23 |
let morph_dict = window.lang_dict[store.state.language]['morphologies'];
|
24 |
this.element.querySelector('#agents_list_title').innerHTML = `<strong>${dict['title']}</strong>`;
|
25 |
this.element.querySelector('#agents_list').innerHTML = store.state.agents.map(agent => {
|
26 |
-
let age = agent.age == "adult" ? "" : " (" + window.lang_dict[window.get_language()]['morphologies'][agent.age] + ")";
|
27 |
// Creates a list item for each agent
|
28 |
return `<li name="agent-list-item" class="list-group-item d-flex justify-content-between align-items-center px-0 py-1">
|
29 |
|
@@ -36,7 +35,7 @@ export default class AgentsList extends Component {
|
|
36 |
|
37 |
<!-- Text field of the name of the agent -->
|
38 |
<div class="form-group">
|
39 |
-
<input name="agentNameArea" type="text" class="form-control w-75 mx-1" placeholder="${agent.name
|
40 |
</div>
|
41 |
|
42 |
<!-- Follow switch -->
|
|
|
23 |
let morph_dict = window.lang_dict[store.state.language]['morphologies'];
|
24 |
this.element.querySelector('#agents_list_title').innerHTML = `<strong>${dict['title']}</strong>`;
|
25 |
this.element.querySelector('#agents_list').innerHTML = store.state.agents.map(agent => {
|
|
|
26 |
// Creates a list item for each agent
|
27 |
return `<li name="agent-list-item" class="list-group-item d-flex justify-content-between align-items-center px-0 py-1">
|
28 |
|
|
|
35 |
|
36 |
<!-- Text field of the name of the agent -->
|
37 |
<div class="form-group">
|
38 |
+
<input name="agentNameArea" type="text" class="form-control w-75 mx-1" placeholder="${agent.name}">
|
39 |
</div>
|
40 |
|
41 |
<!-- Follow switch -->
|
js/ui_state/components/morphologies_list.js
CHANGED
@@ -76,20 +76,16 @@ export default class MorphologiesList extends Component {
|
|
76 |
.filter(m => m.morphology == store.state.morphologies[index].morphology)
|
77 |
.flatMap(morphology => morphology.seeds)
|
78 |
.map((seedEntry, idx) => {
|
79 |
-
|
80 |
-
// Splits seed name between name and age
|
81 |
-
let seed = seedEntry.name.split('/');
|
82 |
-
let name = seed[0];
|
83 |
-
let age = seed[1];
|
84 |
|
85 |
// Adds options and optgroups
|
86 |
if(seed_names.hasOwnProperty(name)){
|
87 |
-
seed_names[name] += `<option value="${seedEntry.path}">${name
|
88 |
|
89 |
}
|
90 |
else {
|
91 |
seed_names[name] = `<optgroup label=${name}>
|
92 |
-
<option value="${seedEntry.path}">${name
|
93 |
}
|
94 |
});
|
95 |
let options = [];
|
@@ -111,11 +107,10 @@ export default class MorphologiesList extends Component {
|
|
111 |
this.element.querySelectorAll('button[name="addAgentButton"]').forEach((span, index) => {
|
112 |
span.addEventListener('click', () => {
|
113 |
let morph = store.state.morphologies[index];
|
114 |
-
let
|
115 |
store.dispatch('addAgent', {
|
116 |
morphology: morph.morphology,
|
117 |
-
name:
|
118 |
-
age: seed[1],
|
119 |
path: morph.seeds[store.state.currentSeedsIdx[morph.morphology]].path,
|
120 |
init_pos: null
|
121 |
});
|
|
|
76 |
.filter(m => m.morphology == store.state.morphologies[index].morphology)
|
77 |
.flatMap(morphology => morphology.seeds)
|
78 |
.map((seedEntry, idx) => {
|
79 |
+
let name = seedEntry.name;
|
|
|
|
|
|
|
|
|
80 |
|
81 |
// Adds options and optgroups
|
82 |
if(seed_names.hasOwnProperty(name)){
|
83 |
+
seed_names[name] += `<option value="${seedEntry.path}">${name}</option>`;
|
84 |
|
85 |
}
|
86 |
else {
|
87 |
seed_names[name] = `<optgroup label=${name}>
|
88 |
+
<option value="${seedEntry.path}">${name}</option>`;
|
89 |
}
|
90 |
});
|
91 |
let options = [];
|
|
|
107 |
this.element.querySelectorAll('button[name="addAgentButton"]').forEach((span, index) => {
|
108 |
span.addEventListener('click', () => {
|
109 |
let morph = store.state.morphologies[index];
|
110 |
+
let name = morph.seeds[store.state.currentSeedsIdx[morph.morphology]].name;
|
111 |
store.dispatch('addAgent', {
|
112 |
morphology: morph.morphology,
|
113 |
+
name: name,
|
|
|
114 |
path: morph.seeds[store.state.currentSeedsIdx[morph.morphology]].path,
|
115 |
init_pos: null
|
116 |
});
|
js/ui_state/store/actions.js
CHANGED
@@ -52,7 +52,6 @@ export default {
|
|
52 |
context.commit('addAgent', {
|
53 |
morphology: agent.morphology,
|
54 |
name: agent.name,
|
55 |
-
age: agent.age,
|
56 |
path: agent.path,
|
57 |
init_pos: agent.init_pos
|
58 |
});
|
|
|
52 |
context.commit('addAgent', {
|
53 |
morphology: agent.morphology,
|
54 |
name: agent.name,
|
|
|
55 |
path: agent.path,
|
56 |
init_pos: agent.init_pos
|
57 |
});
|
js/ui_state/store/mutations.js
CHANGED
@@ -155,7 +155,6 @@ export default {
|
|
155 |
policies: state.agents.map(a => {
|
156 |
return {
|
157 |
name: a.name,
|
158 |
-
age: a.age,
|
159 |
path: a.path
|
160 |
};
|
161 |
}),
|
@@ -200,13 +199,13 @@ export default {
|
|
200 |
/**
|
201 |
* Adds the given agent to the environment and renders it.
|
202 |
* @param state {Object} - UI state
|
203 |
-
* @param payload {{morphology: string, name: string,
|
204 |
* @return {Object} - UI state
|
205 |
*/
|
206 |
addAgent(state, payload) {
|
207 |
state.agents.push(payload);
|
208 |
if(window.game != null){
|
209 |
-
window.game.env.add_agent(payload.morphology, {name: payload.name,
|
210 |
window.game.env.render();
|
211 |
}
|
212 |
return state;
|
|
|
155 |
policies: state.agents.map(a => {
|
156 |
return {
|
157 |
name: a.name,
|
|
|
158 |
path: a.path
|
159 |
};
|
160 |
}),
|
|
|
199 |
/**
|
200 |
* Adds the given agent to the environment and renders it.
|
201 |
* @param state {Object} - UI state
|
202 |
+
* @param payload {{morphology: string, name: string, path: string, init_pos: {x: number, y: number}}}
|
203 |
* @return {Object} - UI state
|
204 |
*/
|
205 |
addAgent(state, payload) {
|
206 |
state.agents.push(payload);
|
207 |
if(window.game != null){
|
208 |
+
window.game.env.add_agent(payload.morphology, {name: payload.name, path: payload.path}, payload.init_pos);
|
209 |
window.game.env.render();
|
210 |
}
|
211 |
return state;
|
ui.js
CHANGED
@@ -286,24 +286,44 @@ globalElementsInstance.render();
|
|
286 |
/*
|
287 |
* Fetches the available morphologies and policies from the JSON file
|
288 |
*/
|
289 |
-
fetch('
|
290 |
.then(resp => resp.text().then(body => {
|
291 |
-
|
292 |
-
return window.agent_policies;
|
293 |
}))
|
294 |
-
.then(
|
295 |
-
|
296 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
297 |
|
298 |
-
|
|
|
299 |
store.dispatch('addMorphology', {
|
300 |
-
morphology:
|
301 |
-
seeds:
|
302 |
seed["idx"] = index;
|
303 |
return seed;
|
304 |
})
|
305 |
});
|
306 |
-
}
|
307 |
});
|
308 |
});
|
309 |
|
|
|
286 |
/*
|
287 |
* Fetches the available morphologies and policies from the JSON file
|
288 |
*/
|
289 |
+
fetch('https://huggingface.co/api/models?filter=teach-my-agent-parkour')
|
290 |
.then(resp => resp.text().then(body => {
|
291 |
+
return JSON.parse(body);
|
|
|
292 |
}))
|
293 |
+
.then(models => {
|
294 |
+
let morphologies = {}
|
295 |
+
let promises = []
|
296 |
+
models.forEach(model => {
|
297 |
+
promises.push(
|
298 |
+
fetch('https://huggingface.co/'+model.id+'/raw/main/ta-config.json')
|
299 |
+
.then(result => result.text().then(body => {
|
300 |
+
let policy = JSON.parse(body);
|
301 |
+
if(!(policy["body"] in morphologies)){
|
302 |
+
morphologies[policy["body"]] = {
|
303 |
+
"morphology": policy["body"],
|
304 |
+
"seeds": []
|
305 |
+
}
|
306 |
+
}
|
307 |
+
|
308 |
+
morphologies[policy["body"]]["seeds"].push({
|
309 |
+
"seed": policy["seed"],
|
310 |
+
"name": policy["name"],
|
311 |
+
"path": 'https://huggingface.co/'+model.id+'/resolve/main'
|
312 |
+
})
|
313 |
+
}))
|
314 |
+
);
|
315 |
+
});
|
316 |
|
317 |
+
Promise.all(promises).then(() => {
|
318 |
+
for (const [key, value] of Object.entries(morphologies)) {
|
319 |
store.dispatch('addMorphology', {
|
320 |
+
morphology: value["morphology"],
|
321 |
+
seeds: value["seeds"].map((seed, index) => {
|
322 |
seed["idx"] = index;
|
323 |
return seed;
|
324 |
})
|
325 |
});
|
326 |
+
}
|
327 |
});
|
328 |
});
|
329 |
|