-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathoperations_cpu.h
More file actions
105 lines (91 loc) · 4.03 KB
/
operations_cpu.h
File metadata and controls
105 lines (91 loc) · 4.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <string>
namespace rl_tools{
template <typename DEVICE, typename SPEC>
std::string json(DEVICE&, MyPendulum<SPEC>& env, typename MyPendulum<SPEC>::Parameters& parameters){
return "{}";
}
template <typename DEVICE, typename SPEC>
std::string json(DEVICE&, MyPendulum<SPEC>& env, typename MyPendulum<SPEC>::Parameters& parameters, typename MyPendulum<SPEC>::State& state){
std::string json = "{";
json += "\"theta\":" + std::to_string(state.theta) + ",";
json += "\"theta_dot\":" + std::to_string(state.theta_dot);
json += "}";
return json;
}
template <typename DEVICE, typename SPEC>
std::string get_ui(DEVICE& device, MyPendulum<SPEC>& env){
// Implement the functions `export async function render(ui_state, parameters, state, action)` and `export async function init(canvas, parameters, options)` and `export` them so that they are available as ES6 imports
// Please have a look at https://studio.rl.tools which helps you create render functions interactively
std::string ui = R"RL_TOOLS_LITERAL(
export async function init(canvas, options){
// Simply saving the context for 2D environments
return {
ctx: canvas.getContext('2d')
}
}
export async function render(ui_state, parameters, state, action) {
const ctx = ui_state.ctx
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
const centerX = ctx.canvas.width / 2;
const centerY = ctx.canvas.height / 2;
const canvasWidth = ctx.canvas.width;
const pendulumLength = canvasWidth * 0.2;
const bobRadius = canvasWidth * 0.02;
const pivotRadius = canvasWidth * 0.01;
// Draw the Pendulum
const adjustedTheta = state.theta - Math.PI;
const pendulumX = centerX + pendulumLength * Math.sin(adjustedTheta);
const pendulumY = centerY + pendulumLength * Math.cos(adjustedTheta);
ctx.beginPath();
ctx.moveTo(centerX, centerY);
ctx.lineTo(pendulumX, pendulumY);
ctx.lineWidth = canvasWidth * 0.008;
ctx.strokeStyle = 'black';
ctx.stroke();
ctx.beginPath();
ctx.arc(pendulumX, pendulumY, bobRadius, 0, 2 * Math.PI);
ctx.fillStyle = '#7DB9B6';
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.arc(centerX, centerY, pivotRadius, 0, 2 * Math.PI);
ctx.fillStyle = 'black';
ctx.fill();
ctx.stroke();
// Draw torque arc
const torqueMagnitude = -Math.max(-1, Math.min(action[0], 1));
const arrowRadius = canvasWidth * 0.08;
const magnitudeRadians = (Math.PI * 2 / 3 * torqueMagnitude);
const startAngle = Math.PI / 2 + (torqueMagnitude > 0 ? 0 : magnitudeRadians);
const endAngle = Math.PI / 2 + (torqueMagnitude < 0 ? 0 : magnitudeRadians);
ctx.beginPath();
ctx.arc(centerX, centerY, arrowRadius, startAngle, endAngle);
ctx.strokeStyle = 'black';
ctx.lineWidth = canvasWidth * 0.008;
ctx.stroke();
// Draw arrowhead
const arrowAngle = torqueMagnitude > 0 ? endAngle : startAngle;
const arrowHeadAngularOffset = torqueMagnitude * Math.PI/180*20
const arrowX = centerX + arrowRadius * Math.cos(arrowAngle + arrowHeadAngularOffset);
const arrowY = centerY + arrowRadius * Math.sin(arrowAngle + arrowHeadAngularOffset);
const headlen = canvasWidth * 0.04 * Math.min(Math.abs(torqueMagnitude)*2, 1);
const angleOffset = Math.PI / 6;
const rotationAngle = Math.PI / 2 + (torqueMagnitude > 0 ? 0 : Math.PI);
ctx.beginPath();
ctx.moveTo(arrowX, arrowY);
ctx.lineTo(
arrowX - headlen * Math.cos(arrowAngle + arrowHeadAngularOffset/2 - angleOffset + rotationAngle),
arrowY - headlen * Math.sin(arrowAngle + arrowHeadAngularOffset/2 - angleOffset + rotationAngle)
);
ctx.lineTo(
arrowX - headlen * Math.cos(arrowAngle + arrowHeadAngularOffset/2 + angleOffset + rotationAngle),
arrowY - headlen * Math.sin(arrowAngle + arrowHeadAngularOffset/2 + angleOffset + rotationAngle)
);
ctx.lineTo(arrowX, arrowY);
ctx.fillStyle = 'black';
ctx.fill();
}
)RL_TOOLS_LITERAL";
return ui;
}
}