Кастомный дайв-комп
Модераторы: Максим Васильев, трофи, DukeSS, KWAK
-
- Участник
- Сообщения: 70
- Зарегистрирован: 13-12-2016 13:11
Мысли в слух,если чем то может помочь,то хорошо.Вариант устройства автомобильных датчиков давления в шинах.Система ТПМС.Работает,например штатная у хонд,на частоте 315мГц.По сути-датчик давления+передающее устройство по каналу связи,батарейка "таблеткой"
Спасибо! 315 МГц - один из вариантов реализации:)Nikitos zamkad писал(а):Мысли в слух,если чем то может помочь,то хорошо.Вариант устройства автомобильных датчиков давления в шинах.Система ТПМС.Работает,например штатная у хонд,на частоте 315мГц.По сути-датчик давления+передающее устройство по каналу связи,батарейка "таблеткой"
пара трансмиттер + ресивер в р-не 100руб выходит, но как оно все себя в толще воды поведет... черт его знает:)
с другой стороны на дистанцию 2.5метра по результатам мат.моделирования достает даже bluetooth
![Smile :)](./images/smilies/icon_smile.gif)
в общем до интеграции с баллоном далеко еще, но в целом сложностей уже меньше:)
CMAS ***
Из-за работы оочень мало времени получается уделять игрушке...
На данный момент научились нормально считать NDL, деку(ZH-L16C), pp02(вывод пока отключил), CNS(вывод отключил пока), noflytime(вывод пока тоже отключил).
Оказалось, что моя адруино китайская работает на 12МГц, вместо 16МГц... это большая разница очень.
Вывод и расчет некоторых показателей отключить пришлось из-за их ресурсоемкости и относительно бесполезности при одиночном дайве на воздухе до 40 метров.
Кому интересно - скоро выложу исходники в открытый репозиторий(пока что они похожи на отрыжку посейдона, мягко выражаясь:)), судя по всему, на адруине это будет первый более-менее адекватный вариант в паблике.
Общая себестоимость на данный момент:
- 1 т.р. Arduino Mega 2560 + TFT 3.2" 320x480
- ~2 т.р. MS5803-14BA - датчик давления и температуры
- ~600 руб BNO055(9-ти осевой IMU), компас, акселерометры, гироскопы) 3d-компас. Можно было использовать компас и за $2, но BNO055 лично для меня является отработанным для пипец какого точного позиционирования всяких коптеров, самолетиков и прочее.
- комплект проводов 210руб.
_______________
<4т.р. за дайв-комп:)
Правда контроллер заменю на ARM по причине того, что математика ждет много ресурсов, а 8-ми битный AVR даже умножать не умеет, не говоря уже, что 32-х битные числа обрабатываются за 4 цикла....
В общем - фото и видео. https://www.youtube.com/watch?v=FMh0QHdlCMk
На данный момент научились нормально считать NDL, деку(ZH-L16C), pp02(вывод пока отключил), CNS(вывод отключил пока), noflytime(вывод пока тоже отключил).
Оказалось, что моя адруино китайская работает на 12МГц, вместо 16МГц... это большая разница очень.
Вывод и расчет некоторых показателей отключить пришлось из-за их ресурсоемкости и относительно бесполезности при одиночном дайве на воздухе до 40 метров.
Кому интересно - скоро выложу исходники в открытый репозиторий(пока что они похожи на отрыжку посейдона, мягко выражаясь:)), судя по всему, на адруине это будет первый более-менее адекватный вариант в паблике.
Общая себестоимость на данный момент:
- 1 т.р. Arduino Mega 2560 + TFT 3.2" 320x480
- ~2 т.р. MS5803-14BA - датчик давления и температуры
- ~600 руб BNO055(9-ти осевой IMU), компас, акселерометры, гироскопы) 3d-компас. Можно было использовать компас и за $2, но BNO055 лично для меня является отработанным для пипец какого точного позиционирования всяких коптеров, самолетиков и прочее.
- комплект проводов 210руб.
_______________
<4т.р. за дайв-комп:)
Правда контроллер заменю на ARM по причине того, что математика ждет много ресурсов, а 8-ми битный AVR даже умножать не умеет, не говоря уже, что 32-х битные числа обрабатываются за 4 цикла....
В общем - фото и видео. https://www.youtube.com/watch?v=FMh0QHdlCMk
CMAS ***
a водонепроницаемый корпус?kittzbiz писал(а):<4т.р. за дайв-комп:)
![Smile :)](./images/smilies/icon_smile.gif)
Bangkok Women Really Are Fellas
Верить нельзя никому. Если человек имеет карточку дайв-мастера, это не означает что он не дебил. © Катерина Р
Хто не в боковій підвісці, той - москаль! © S.S. "Drip"
Верить нельзя никому. Если человек имеет карточку дайв-мастера, это не означает что он не дебил. © Катерина Р
Хто не в боковій підвісці, той - москаль! © S.S. "Drip"
Два момена:
1) кварц можно перепаять, тогда и 16 МГц будут;
2) А не жирновата ли 2560-я мега для всего этого? Неужели код в 328-ю не влезает?
1) кварц можно перепаять, тогда и 16 МГц будут;
2) А не жирновата ли 2560-я мега для всего этого? Неужели код в 328-ю не влезает?
Credo quia absurdum est.
Сейчас будет "накасявыкуси":)vovanx писал(а):a водонепроницаемый корпус?kittzbiz писал(а):<4т.р. за дайв-комп:)
Проектировщик есть, рассчет+3д модель не проблема(он по совместительству мой инструктор КМАС**)
![Smile :)](./images/smilies/icon_smile.gif)
В гараже стоит станок с ЧПУ, с фрезой мощностью больше 2 кВт, хоть дюраль обрабатывай.
А вообще в планах - банальный корпус из пластика, распечатанный на 3д принтере(в каждом городе есть уже такие точки) и кусок оргстекла в качестве крышки.
Если будет "хиленько" - маслом залью и пофиг на него.
ну ок. еще, пусть с запасом будет 2т.р. на корпус:)
CMAS ***
п.1 невыполним. 12МГц кварц стоит из-за тогда, что на плате CH340 стоит, для uart, так вот 12МГц именно для нее нужен. и прошивка ардуино откалибрована на 12МГц.snb писал(а):Два момена:
1) кварц можно перепаять, тогда и 16 МГц будут;
2) А не жирновата ли 2560-я мега для всего этого? Неужели код в 328-ю не влезает?
2) По объему ПЗУ с избытком.
а вот ОЗУ всего 8Кб. это "впритык", т.к. банальные массивы float N2[16] и float He[16], сюда же double n2_exposition[16] & double he_exposition[16] уже занимают больше 200 байт, а при расчетах часто нужно их копировать во временные структуры, отсюда имеем(минимум, который я смог оптимизировать) 4 структуры:
float N2[4][16];
float He[4][16];
double n2_exposition[4][16];
double he_exposition[4][16];
уже 1кб минус. и это только статические данные.
банальный расчет NDL выглядит следующим образом:
Код: Выделить всё
void NDL_calculation(enum stages_e stage, global_life_data_t *data, const gaslist_t *gaslist, const buehlmann_configuration_t *config, int *remaining_no_stop_time_in_seconds)
{
int ci = -1;
float tissue_saturation_limit[16];
float partial_pressure = -1.0;
float amb_pressure = -1;
int ascend_duration = 0;
bool status = false;
long counter = -1;
float zero_gf_tissue_value_at_surface = -1.0;
zero_gf_tissue_value_at_surface = (data->pressureSurface_bar - water_vapour_pressure) * fraction_N2_air;
*remaining_no_stop_time_in_seconds = 0;
// ambient will be surface
// is different if GF_high exists.
// sat_limit = ( amb/(b*GF) + a ) * (GF*b - b + 1)
// for NDL: amb = surface, GF = GF_high
for (ci=0;ci<16;ci++)
tissue_saturation_limit[ci] = config->gf_high * ((data->pressureSurface_bar / buehlmann_N2_b[ci]) + buehlmann_N2_a[ci] - zero_gf_tissue_value_at_surface) + zero_gf_tissue_value_at_surface;
// calc saturation at beginning of ascend
// could be Schreiner Equation
// or simplified with r = 0 and several steps
// split into 20 seconds (3.33 mtrs) and one minute (10 mtrs) steps
// change is subtracted (instead of added)
ascend_duration = 0;
amb_pressure = data->pressureSurface_bar;
while(amb_pressure < data->pressureAmbient_bar)
{
ascend_duration += 20;
partial_pressure = (amb_pressure - water_vapour_pressure) * fraction_N2_air;
for (ci=0;ci<16;ci++)
{
if((partial_pressure - tissue_saturation_limit[ci]) > 0)
tissue_saturation_limit[ci] -= config->saturation_multiplier * (partial_pressure - tissue_saturation_limit[ci]) * buehlmann_N2_factor_expositon_20_seconds[ci];
else
tissue_saturation_limit[ci] -= config->desaturation_multiplier * (partial_pressure - tissue_saturation_limit[ci]) * buehlmann_N2_factor_expositon_20_seconds[ci];
}
amb_pressure += pressure_change_in_20_secs;
}
// now the recent depth is reached.
// calculation of time to reach tissue_saturation_limit
stage_copy_data_from_to(stage, st_deco_test);
status = true;
counter = -20;
while(status && (counter < MAX_NDL_IN_SECONDS))
{
tissues_exposure(st_deco_test,20,data,gaslist,config);
for (ci=0;ci<16;ci++)
{
if((tissue_N2_saturation[st_deco_test][ci] + tissue_He_saturation[st_deco_test][ci]) >= tissue_saturation_limit[ci])
status = false;
}
counter += 20;
}
*remaining_no_stop_time_in_seconds = counter;
// if(counter < MAX_NDL_IN_SECONDS)
// *remaining_no_stop_time_in_seconds -= ascend_duration;
*remaining_no_stop_time_in_seconds = Max(0, *remaining_no_stop_time_in_seconds);
// Serial.println("=============");
// Serial.print("remaining_no_stop_time_in_seconds: ");
// Serial.println(*remaining_no_stop_time_in_seconds);
// Serial.print("counter: ");
// Serial.println(counter);
// Serial.println("=============");
}
на самом деле от меги 2560 не хватает именно скорости.
Расход ОЗУ я оптимизирую максимально. Сейчас свободно примерно 3.5Кб из 8Кб.
Но скорости не хватает катастрофически. Расчет деко-таблицы парализует остальные задачи почти на 300мс. (это быстро, да, но критично, что бы задача выполнялась не более 50мс).
Благо Ардуино обеспечивает совместимость, поэтому просто выкидываем Mega 2560, ставим Arduino Due(84МГц, 96кб ОЗУ, 512Кб флеш) и просто загоняем туда данную прошивку.(может быть потребуется использовать другую либу для экрана), но не более. все остальное совсестимо 1-в-1.
Собственно DUE уже лежит рядом и проверена, но из-за оссобенностей работы c ARM процессором пока что продолжаю писать все под Мегу.
Да и спортивный интерес, уместить ВСЕ в 12Мгц+8кб ОЗУ... с учетом экрана 320х480х2байта на пиксель
![Smile :)](./images/smilies/icon_smile.gif)
CMAS ***
Довльно большой экран получается, требования по корпусу будут незаурядными. Агрудина около 105x55мм размером, то есть порядка 60 квадратных сантиметров площадь, на которую давит вода (если сверху смотреть). Это под 250 килограмм давления на глубине в 40 метров. Вроде как и не много, но пластик будет гнуть, вынуждая отдалять от него экран. А воздушный зазор приведёт к бликам. Либо брать лист от 8мм и толще.
Дальше по поводу 3Д печати. Не знаю, что там с прочностью и водонепронецаемостью, но есть противные моменты, которые тяжело выполнить на напечатанном корпуса. Это геметизация огранов управления и датчика. Качество поверхности у 3Д-печати такое, что так просто О-рингом не уплотнить - у датчика допуск по посадке очень небольшой вроде.
И любопытно по органам управления - в умете их нет, тач-скрин работать не будет. Предполагается только полностью автоматический режим и всё? Или управление акселерометром?
По поводу 8-ми бит. Конечно, не идеальные условия. Но и скорость обработки не требуется особая, тут лишь бы хватило ОЗУ.
А так - для расчетов стандартная частота дискретизации - 1 секунда, можно даже реже. Для вывода на экран - тоже. Ну, чтобы не было ощущения тормознутости, можно 2-3 раза в секунду снимать данные с датчика глубины и показывать их на экране, но счиатать нет смысла с высокой частотой. Так как комп рекреационный - ему не нужно считать длинныую декомпрессию, а за секунду мега может много всего посчитать. И даже если информацию о декомпрессии/цнс считать по данным глубины с интервалом в 5 секунд - точность вообще не пострадает.
Дальше по поводу 3Д печати. Не знаю, что там с прочностью и водонепронецаемостью, но есть противные моменты, которые тяжело выполнить на напечатанном корпуса. Это геметизация огранов управления и датчика. Качество поверхности у 3Д-печати такое, что так просто О-рингом не уплотнить - у датчика допуск по посадке очень небольшой вроде.
И любопытно по органам управления - в умете их нет, тач-скрин работать не будет. Предполагается только полностью автоматический режим и всё? Или управление акселерометром?
По поводу 8-ми бит. Конечно, не идеальные условия. Но и скорость обработки не требуется особая, тут лишь бы хватило ОЗУ.
А так - для расчетов стандартная частота дискретизации - 1 секунда, можно даже реже. Для вывода на экран - тоже. Ну, чтобы не было ощущения тормознутости, можно 2-3 раза в секунду снимать данные с датчика глубины и показывать их на экране, но счиатать нет смысла с высокой частотой. Так как комп рекреационный - ему не нужно считать длинныую декомпрессию, а за секунду мега может много всего посчитать. И даже если информацию о декомпрессии/цнс считать по данным глубины с интервалом в 5 секунд - точность вообще не пострадает.
Воооо. Примерно так же я и думал насчет скорости... но давайте по деталям, которые сейчас познал на практике...)vsd писал(а):Довльно большой экран получается, требования по корпусу будут незаурядными. Агрудина около 105x55мм размером, то есть порядка 60 квадратных сантиметров площадь, на которую давит вода (если сверху смотреть). Это под 250 килограмм давления на глубине в 40 метров. Вроде как и не много, но пластик будет гнуть, вынуждая отдалять от него экран. А воздушный зазор приведёт к бликам. Либо брать лист от 8мм и толще.
Дальше по поводу 3Д печати. Не знаю, что там с прочностью и водонепронецаемостью, но есть противные моменты, которые тяжело выполнить на напечатанном корпуса. Это геметизация огранов управления и датчика. Качество поверхности у 3Д-печати такое, что так просто О-рингом не уплотнить - у датчика допуск по посадке очень небольшой вроде.
И любопытно по органам управления - в умете их нет, тач-скрин работать не будет. Предполагается только полностью автоматический режим и всё? Или управление акселерометром?
По поводу 8-ми бит. Конечно, не идеальные условия. Но и скорость обработки не требуется особая, тут лишь бы хватило ОЗУ.
А так - для расчетов стандартная частота дискретизации - 1 секунда, можно даже реже. Для вывода на экран - тоже. Ну, чтобы не было ощущения тормознутости, можно 2-3 раза в секунду снимать данные с датчика глубины и показывать их на экране, но счиатать нет смысла с высокой частотой. Так как комп рекреационный - ему не нужно считать длинныую декомпрессию, а за секунду мега может много всего посчитать. И даже если информацию о декомпрессии/цнс считать по данным глубины с интервалом в 5 секунд - точность вообще не пострадает.
1) по поводу пластика и давления... согласен. там давление приличное. именно поэтому и остается вариант "залью маслом и пофигу".
По качеству 3д печать - обратно согласен! Но в гараже кроме станка с ЧПУ еще и рейсмус есть(т.е. основные важные моменты сошлифуются в идеальную поверхность) - тоже не проблема.
2) тачскрин под водой - жесть) нет, не планируется даже:) Несколько клавиш для управления режимами в дальнейшем будет. Для первых тестов под водой кнопки не нужны будут, все сделаю преднастроенным.
Насчет управления акселерометром вообще не понял. Зачем и как вы собираетесь управлять датчиком ускорения?(акселерометры и гироскопы нужны для коррекции веткора Euler'а, то бишь вектора магнитометра)
3) Скорость и ОЗУ. Да. Мега может много чего посчитать. И она много чего считает, вы представляете себе объем вычислений с 32-бит значениями, которые сами по себе выполняются в 16 раз медленнее, чем 8 бит(16 крат - это пример на сложении двух 32бит чисел), да еще и при отсутствиии аппаратных умножителей и делителей:) сейчас "лишь бы ОЗУ хватило"(ее теперь точно хватит, т.к. уже самое главное позади:)). А вот со скоростью - проблема. пока идет расчет - это "пауза" для всех остальных расчетов, т.к. с обработкой прерываний у ардуины есть определенные родовые травмы:)
Это плата за упрощение разработки.
т.е. в момент расчета если на 100мс задержится процедура, которая делает dive_time++, то за 10 минут под водой мы имеем не много не мало а, 100*60*10=60000мс, т.е. 1 минуту "джетлага", который является потеряной минутой NDL, да и вообще кривой расчет деки потом.
Про ЦНС молчу вообще:)
Это накапливаемая ошибка, к сожалению, поэтому я для себя установил планку накопления не более 5мс в минуту, что позволит обеспечить достаточную точность.
CMAS ***
Кстати, о производительности. Месяц назад, скучая на декомпрессии, сказал висящему на руке Сивучу, что кислорода у меня больше нет и предложил ему пересчитать деку используя донный газ. Расчет декомпрессии занял 7 (семь!) минут, закончившись абсурдным результатом в 2500+ минут. Я даже думал, что он не раздуплится никогда ![Smile :)](./images/smilies/icon_smile.gif)
![Smile :)](./images/smilies/icon_smile.gif)
ахахаххахахахахахахах!!!! Блин) Скажите спасибо, что вообще осилил))))) там цифры ппц какие)vsd писал(а):Кстати, о производительности. Месяц назад, скучая на декомпрессии, сказал висящему на руке Сивучу, что кислорода у меня больше нет и предложил ему пересчитать деку используя донный газ. Расчет декомпрессии занял 7 (семь!) минут, закончившись абсурдным результатом в 2500+ минут. Я даже думал, что он не раздуплится никогда
у меня пока что даже при смене газа на "сложный" для расчета все укладывается в 20-30 сек, но и цифры возхитительные получаются)))
это уже на АРМе будет, а лучше на STM32:)
CMAS ***
Есть такие компы, которые управляются ударами по корпусу. Как минимум это liquivision, может ещё кто есть.kittzbiz писал(а):Насчет управления акселерометром вообще не понял. Зачем и как вы собираетесь управлять датчиком ускорения?
Я немного представляю суть расчетов (лет 6 назад для знакомства с темой накропал себе кривенький планировщик на поиграться, https://github.com/dmitryshagin/quickDe ... zhl16.java). И возможности меги тоже немного представляю - года три назад делал на ней динамическую тримиксную мешалку (https://github.com/dmitryshagin/dynamic_blender) (помимо десятков других проектов)kittzbiz писал(а): 3) Скорость и ОЗУ. Да. Мега может много чего посчитать. И она много чего считает, вы представляете себе объем вычислений с 32-бит значениями, которые сами по себе выполняются в 16 раз медленнее, чем 8 бит(16 крат - это пример на сложении двух 32бит чисел), да еще и при отсутствиии аппаратных умножителей и делителей:) сейчас "лишь бы ОЗУ хватило"(ее теперь точно хватит, т.к. уже самое главное позади:)). А вот со скоростью - проблема. пока идет расчет - это "пауза" для всех остальных расчетов, т.к. с обработкой прерываний у ардуины есть определенные родовые травмы:)
Уверен, это можно обойти. Увеличение времени дайва просто должно быть в прерывании по таймеру (которо только этим и занимается), а расчет деки - в основном цикле. Тогда даже если она по минуте считать будет - ничего смертельного не произойдёт.kittzbiz писал(а): Это плата за упрощение разработки.
т.е. в момент расчета если на 100мс задержится процедура, которая делает dive_time++, то за 10 минут под водой мы имеем не много не мало а, 100*60*10=60000мс, т.е. 1 минуту "джетлага", который является потеряной минутой NDL, да и вообще кривой расчет деки потом.
Правда я никогда не писал под ардуино ни на чем, кроме чистого C, как раз из-за слухов о том, что с прерываниями она не очень дружит. Но слухи эти на практике не пробовал ни подтвердить ни опровергнуть.
Не могу удержаться и не запостить картиночку с компом с этой зверской декомпрессией
X-Deep, кстати, показал примерно такие же цифры (раза в два меньше, но это сути не меняет, порядок тот же), когда у него из любопытства тоже кислород отобрали. Что меня поставило в тупик, так как в планировщике этот дайв примерно на порядок меньше деки даёт на донном газе. Но это оффтоп, сорри.Не знал, извиняюсь!:)Есть такие компы, которые управляются ударами по корпусу. Как минимум это liquivision, может ещё кто есть.
[/quote]Уверен, это можно обойти. Увеличение времени дайва просто должно быть в прерывании по таймеру (которо только этим и занимается), а расчет деки - в основном цикле. Тогда даже если она по минуте считать будет - ничего смертельного не произойдёт.
Правда я никогда не писал под ардуино ни на чем, кроме чистого C, как раз из-за слухов о том, что с прерываниями она не очень дружит. Но слухи эти на практике не пробовал ни подтвердить ни опровергнуть.
Обойти - снести загрузчик и юзать все плюшки. Это на будущее:)
Пока что - задача именно на ардуине собрать.
На самом деле прерывания есть, таймеры есть... но это смело считаем родовой травмой, т.к. реализация кривая - ни словами описать, ни матом сформулировать.
CMAS ***
Посмотрел репозитории:)Я немного представляю суть расчетов (лет 6 назад для знакомства с темой накропал себе кривенький планировщик на поиграться, https://github.com/dmitryshagin/quickDe ... zhl16.java). И возможности меги тоже немного представляю - года три назад делал на ней динамическую тримиксную мешалку (https://github.com/dmitryshagin/dynamic_blender) (помимо десятков других проектов)
Судя по всему на ранних этапах я плотно изучал эту реализацию на Java))
CMAS ***
Надеюсь только в изучательных целях - бо я ой как не уверен в корректности того, что понаписывалkittzbiz писал(а):Судя по всему на ранних этапах я плотно изучал эту реализацию на Java))
![Smile :)](./images/smilies/icon_smile.gif)
Насколько я знаю, проблема с прерываниями на Ардуино это проблема не чипа ATmega, а кривой реализации прерываний в этом Wiring'е. Никто же не мешает забить и писать на чём нравится, хоть на Си со вставками на ассемблере для критичных процедур. Ну и на avr-gcc свет клином не сошёлся.
Credo quia absurdum est.
У atmega всё хорошо с прерываниями. Как и у avr-gcc. Косяки в Arduino IDE - они уже используют прерывания для внутренних процедур и можно сломать лишнего.snb писал(а):Насколько я знаю, проблема с прерываниями на Ардуино это проблема не чипа ATmega, а кривой реализации прерываний в этом Wiring'е. Никто же не мешает забить и писать на чём нравится, хоть на Си со вставками на ассемблере для критичных процедур. Ну и на avr-gcc свет клином не сошёлся.
Кстати, millis() работает через прерывания и даёт время с начала работы программы вне зависимости от процента загрузки ядра. Так что время вычислений не должно быть проблемой.
так и есть)))vsd писал(а):У atmega всё хорошо с прерываниями. Как и у avr-gcc. Косяки в Arduino IDE - они уже используют прерывания для внутренних процедур и можно сломать лишнего.snb писал(а):Насколько я знаю, проблема с прерываниями на Ардуино это проблема не чипа ATmega, а кривой реализации прерываний в этом Wiring'е. Никто же не мешает забить и писать на чём нравится, хоть на Си со вставками на ассемблере для критичных процедур. Ну и на avr-gcc свет клином не сошёлся.
Кстати, millis() работает через прерывания и даёт время с начала работы программы вне зависимости от процента загрузки ядра. Так что время вычислений не должно быть проблемой.
как раз только millis() и micros() спасают) от второго правда, толку - только на замерах)
CMAS ***
Ну да, в ознакомительных, вообще не понимал с чего начать, и кто как делает)))vsd писал(а):Надеюсь только в изучательных целях - бо я ой как не уверен в корректности того, что понаписывалkittzbiz писал(а):Судя по всему на ранних этапах я плотно изучал эту реализацию на Java))В частности меня смущает учает давления водяного пара (его зачем-то везде отдельно вычитают из давления, во всех планировщиках, что я видел), и смущает расчет градиент-фактора. Точнее не он сам, а то, что он у всех софтин, которыми я пользовался, считается по-разному. Где-то от глубины первой остановик, где-то от максимально достигнутой глубины. И верхний GF не везде посчитан по поверхности, например, в GUE DecoPlaner, похоже, верхний предел счиатется по последней остановке (или по 3-м метрам, не помню точно). В общем есть нюансы.
Аналогично, сходу нашел пяток разных реализаций, которые дают абсолютно разные реализации....
и такая же фигня с градиентами, сейчас, когда уже хотя бы завелось все - сижу читаю про градиент, т.к. с ним, оказалось, гораздо больше проблем, чем думал...
CMAS ***