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 |
|