Skip to content

Commit

Permalink
Add Silo and Ditch PROTO models (#6295)
Browse files Browse the repository at this point in the history
* Add Ditch PROTO

* Add Silo

* Update documentation url

* Update Changelog

* Update projects/objects/buildings/protos/Silo.proto

Co-authored-by: Benjamin Délèze <benjamin.deleze@cyberbotics.com>

* Update projects/objects/floors/protos/Ditch.proto

Co-authored-by: Benjamin Délèze <benjamin.deleze@cyberbotics.com>

* Update Silo.proto

* Update Silo.proto

* Improve JS in Silo.proto

* Update paramete descriptions in Ditch.proto

* Add new PROTO objects in boomer.wbt

* Update Silo PROTO

---------

Co-authored-by: Benjamin Délèze <benjamin.deleze@cyberbotics.com>
  • Loading branch information
stefaniapedrazzi and Benjamin Délèze authored Jul 5, 2023
1 parent 46f8efa commit 281e6a9
Show file tree
Hide file tree
Showing 8 changed files with 517 additions and 1,781 deletions.
2 changes: 2 additions & 0 deletions docs/reference/changelog-r2023.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Webots R2023b Revision 1
Released on XXX XXth, 2023.
- New Devices and Objects
- Added a model of a silo and a field ditch ([#6289](https://github.com/cyberbotics/webots/pull/6289)).
- Bug fixes
- Fixed errors loading template PROTO if the system user name, the project path, or the temporary directory path contains the `\` character ([#6288](https://github.com/cyberbotics/webots/pull/6288)).

Expand Down
182 changes: 182 additions & 0 deletions projects/objects/buildings/protos/Silo.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
#VRML_SIM R2023b utf8
# license: Copyright Cyberbotics Ltd. Licensed for use only with Webots.
# license url: https://cyberbotics.com/webots_assets_license
# documentation url: https://webots.cloud/run?url=https://github.com/cyberbotics/webots/blob/released/projects/objects/buildings/protos/Silo.proto
# keywords: building/farm
# A steel grain silo.
# template language: javascript

EXTERNPROTO "webots://projects/appearances/protos/CorrugatedMetal.proto"

PROTO Silo [
field SFVec3f translation 0 0 0 # Is `Pose.translation`.
field SFRotation rotation 0 0 1 0 # Is `Pose.rotation`.
field SFFloat radius 3 # Defines the radius of the silo.
field SFFloat height 17 # Defines the height of the silo.
field SFFloat roofHeight 2 # Defines the height of the silo's roof.
field SFString name "silo" # Is `Solid.name`.
field SFBool enableBoundingObject TRUE # Defines whether the silo should have a bounding object.
field SFBool locked FALSE # Is `Solid.locked`.
]
{
%<
let roofHeight = fields.roofHeight.value;
let height = fields.height.value;
let radius = fields.radius.value;

if (radius <= 0) {
radius = fields.radius.defaultValue;
console.error('\'radius\' must be strictly positive. Value reset to ' + radius + '.');
}

if (height <= 2) {
height = fields.height.defaultValue;
console.error('\'height\' must be greater than 2. Value reset to ' + height + '.');
}

if (roofHeight <= 0 || roofHeight >= height) {
roofHeight = fields.roofHeight.defaultValue;
console.error('\'roofHeight\' must be strictly positive and lower than `height`. Value reset to ' + roofHeight + '.');
}

const cylinderHeight = height - roofHeight;
const ladderWidth = 0.7;
const ladderHeight = cylinderHeight * 2 / 3;
const ladderStepSize = 0.5;
const ladderSteps = Math.trunc(ladderHeight / ladderStepSize);
const barHeight = ladderHeight + ladderStepSize;
>%
Solid {
translation IS translation
rotation IS rotation
children [
DEF BODY Pose {
translation 0 0 %<= cylinderHeight * 0.5 >%
children [
Shape {
appearance CorrugatedMetal {
colorOverride 1 0.9696 0.82
textureTransform TextureTransform {
rotation 1.5708
scale %<= cylinderHeight>% %<= 3 * radius >%
}
}
geometry Cylinder {
height %<= cylinderHeight >%
radius %<= radius >%
}
}
]
}
DEF ROOF Pose {
translation 0 0 %<= cylinderHeight + roofHeight * 0.5 >%
children [
Shape {
appearance CorrugatedMetal {
colorOverride 1 0.9696 0.82
textureTransform TextureTransform {
rotation 1.5708
scale %<= radius >% %<= 3 * roofHeight>%
}
}
geometry Cone {
bottomRadius %<= radius >%
height %<= roofHeight >%
subdivision 40
}
}
]
}
DEF LADDER Pose {
translation %<= radius + 0.04 >% 0 0
children [
DEF LEFT_POLE Pose {
translation 0 %<= -ladderWidth * 0.5 - 0.025 >% %<= cylinderHeight + 0.1 + ladderStepSize - barHeight * 0.5 >%
children [
DEF SIDE_POLE Shape {
appearance DEF LADDER_APPEARANCE PBRAppearance {
baseColor 0.603922 0.6 0.588235
roughness 0.8
}
geometry Box {
size 0.05 0.05 %<= barHeight >%
}
}
]
}
DEF RIGHT_POLE Pose {
translation 0 %<= ladderWidth * 0.5 + 0.025 >% %<= cylinderHeight + 0.1 + ladderStepSize - barHeight * 0.5 >%
children [
USE SIDE_POLE
]
}
DEF LEFT_TOP_POLE Pose {
translation %<= -radius * 0.5 - 0.025 >% %<= -ladderWidth * 0.5 - 0.025 >% %<= cylinderHeight + 0.3 >%
children [
DEF TOP_POLE Shape {
appearance DEF LADDER_APPEARANCE PBRAppearance {
baseColor 0.603922 0.6 0.588235
roughness 0.8
}
geometry Box {
size %<= radius >% 0.05 0.1
}
}
]
}
DEF RIGHT_TOP_POLE Pose {
translation %<= -radius * 0.5 - 0.025 >% %<= ladderWidth * 0.5 + 0.025 >% %<= cylinderHeight + 0.3 >%
children [
USE TOP_POLE
]
}
Pose {
translation 0 0 %<= cylinderHeight + 0.1 >%
children [
DEF FOOL Shape {
appearance USE LADDER_APPEARANCE
geometry Box {
size 0.05 %<= ladderWidth >% 0.05
}
}
]
}
%<
let h = cylinderHeight + 0.1;
for (let n = 1; n < ladderSteps; n++) {
h -= ladderStepSize;
>%
Pose {
translation 0 0 %<= h >%
children [
USE FOOL
]
}
%<
}
>%
]
}
]
name IS name
%<
if (fields.enableBoundingObject.value) {
>%
boundingObject Pose {
translation 0 0 %<= height * 0.5>%
children [
Cylinder {
height %<= height >%
radius %<= radius >%
}
]
}
%<
}
>%
locked IS locked
recognitionColors [
0.89 0.89 0.89
]
}
}
Binary file added projects/objects/buildings/protos/icons/Silo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
170 changes: 170 additions & 0 deletions projects/objects/floors/protos/Ditch.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
#VRML_SIM R2023b utf8
# license: Copyright Cyberbotics Ltd. Licensed for use only with Webots.
# license url: https://cyberbotics.com/webots_assets_license
# documentation url: https://webots.cloud/run?url=https://github.com/cyberbotics/webots/blob/released/projects/objects/floors/protos/Ditch.proto
# tags: nonDeterministic
# keywords: primitive/ground
# Randomly generated ditch with optional water.
# template language: javascript

EXTERNPROTO "webots://projects/appearances/protos/SandyGround.proto"

PROTO Ditch [
field SFVec3f translation 0 0 0 # Is `Pose.translation`.
field SFRotation rotation 0 0 1 0 # Is `Solid.rotation`.
field SFString name "ditch" # Is `Solid.name`.
field SFVec3f size 20 5 2 # Defines the size of the ditch.
field SFFloat waterHeight 0.3 # Defines the height of the water in the ditch.
field SFNode appearance SandyGround { textureTransform TextureTransform { scale 5 5 } } # Defines the appearance of the terrain.
field SFInt32 randomSeed 1 # Defines whether the bounds of the terrain should be flat.
]
{
%<
// reference: https://stackoverflow.com/a/42543313/2210777
import * as wbrandom from 'wbrandom.js';

if (fields.randomSeed.value <= 0)
wbrandom.seed(Date.now());
else
wbrandom.seed(fields.randomSeed.value);

function gaussian2d(x, y, amp, cx, cy, sx, sy) {
return amp * Math.exp( - ( ( Math.pow(x - cx, 2) / (2.0 * Math.pow(sx, 2)) ) + (Math.pow(y - cy, 2) / (2.0 * Math.pow(sy, 2)) ) ));
}

// create 256 shuffled numbers repeated twice.
let perm = [];
for (let i = 1; i <= 256; ++i)
perm.splice(wbrandom.integer(i) -1, 0, i);

for (let i = 0; i < 256; ++i)
perm.push(perm[i]);

// generate 256 directions
let dirs = [];
for (let a = 0; a < 256; ++a)
dirs.push([Math.cos(a * 2.0 * Math.PI / 256), Math.sin(a * 2.0 * Math.PI / 256)]);

function noise (x, y, per, dirs, perm) {
function surflet (grid_x, grid_y, dirs, perm) {
const dist_x = Math.abs(x - grid_x);
const dist_y = Math.abs(y - grid_y);
const poly_x = 1 - 6 * Math.pow(dist_x, 5) + 15 * Math.pow(dist_x, 4) - 10 * Math.pow(dist_x, 3);
const poly_y = 1 - 6 * Math.pow(dist_y, 5) + 15 * Math.pow(dist_y, 4) - 10 * Math.pow(dist_y, 3);
const hashed = perm[(perm[(Math.floor(grid_x) % per)] + Math.floor(grid_y) % per)];
const grad = (x - grid_x) * dirs[hashed-1][0] + (y - grid_y) * dirs[hashed-1][1];

return poly_x * poly_y * grad;
}

let int_x = Math.floor(x);
let int_y = Math.floor(y);

return surflet(int_x + 0, int_y + 0, dirs, perm) + surflet(int_x + 1, int_y + 0, dirs, perm) + surflet(int_x + 0, int_y + 1, dirs, perm) + surflet(int_x + 1, int_y + 1, dirs, perm);
}

function fBm (x, y, per, octs, dirs, perm) { // Fractional Brownian motion
let val = 0;
for (let o = 0; o <= octs - 1; ++o)
val = val + (Math.pow(0.5, o) * noise(x * Math.pow(2, o), y * Math.pow(2, o), per * Math.pow(2, o), dirs, perm));

return val;
}

const perlinSize = 128;
const nOctave = 3;

let size = fields.size.value;
if (size.x <= 0 || size.y <= 0 || size.z <= 0) {
size = fields.size.defaultValue;
console.error('\'size\' must be strictly positive. Value reset to ' + size + '.');
}

let yDimension = 10;
const hValues = [0, 0, -size.z * 0.5, -size.z, -size.z, -size.z, -size.z, -size.z * 0.5, 0, 0];

let xDimension = Math.floor(size.x / 0.5);
if (xDimension < 8)
xDimension = 2;

const ySpacing = size.y / (yDimension - 1);

let waterHeight = fields.waterHeight.value;
if (waterHeight >= size.z) {
waterHeight = fields.waterHeight.defaultValue;
console.error('\'waterHeight\' should be lower than `size.z`. Value reset to ' + waterHeight + '.');
}

let heights = []
let minHeight = 0;
for (let i = 0; i < 9; ++i) {
const x = i / xDimension;
for (let j = 0; j < xDimension; ++j) {
let height = hValues[i];
if (i > 0 && i < 7 && nOctave > 0) {
const y = j / yDimension;
height += 0.2 * fBm(x, y, perlinSize, nOctave, dirs, perm);
}
if (height < minHeight)
minHeight = height;
heights.push(height);
}
}
>%
%< if (waterHeight >= 0) { >%
Fluid {
%< } else { >%
Solid {
%< } >%
translation IS translation
rotation IS rotation
children [
%< if (waterHeight >= 0) { >%
DEF WATER_BOX Pose {
translation 0 0 %<= minHeight + waterHeight * 0.5>%
children [
Shape {
appearance PBRAppearance {
baseColor 0.30985 0.464424 0.636667
transparency 0.3
roughness 0.05
metalness 0.9
}
geometry Box {
size %<= size.x >% %<= size.y - 2 * ySpacing >% %<= waterHeight >%
}
}
]
}
Solid {
children [
%< } >%
DEF DITCH_ELEVATION_GRID Pose {
translation %<= - size.x * 0.5 >% %<= -size.y * 0.5 >% 0
children [
Shape {
appearance IS appearance
geometry ElevationGrid {
xDimension %<= xDimension >%
xSpacing %<= size.x / (xDimension - 1) >%
yDimension %<= yDimension >%
ySpacing %<= ySpacing >%
height [
%<= heights.join(', ') >%
]
}
}
]
}
]
name IS name
model "ditch"
boundingObject USE DITCH_ELEVATION_GRID
}
%< if (waterHeight >= 0) { >%
]
viscosity 0.01
boundingObject USE WATER_BOX
}
%< } >%
}
Binary file added projects/objects/floors/protos/icons/Ditch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 281e6a9

Please sign in to comment.