232 lines
9.3 KiB
JavaScript
232 lines
9.3 KiB
JavaScript
let Common = system.getScript("/driverlib/Common.js");
|
|
let Pinmux = system.getScript("/driverlib/pinmux.js");
|
|
let references = system.getScript("/libraries/C2000WARELibraryReferences.js");
|
|
let controller_data = system.getScript("/libraries/control/dcl/controller_data.js");
|
|
|
|
// get the main dropdown lists
|
|
var CONTROLLER_CHOICE_LIST = controller_data.get_dropdown_list('controller');
|
|
var PRECISION_LIST = controller_data.get_dropdown_list('precision');
|
|
var ACCELERATOR_LIST = controller_data.get_dropdown_list('accelerator');
|
|
|
|
// set the default values for each list
|
|
var DEFAULT_CONTROLLER_CHOICE = CONTROLLER_CHOICE_LIST[0].name;
|
|
var DEFAULT_PRECISION = "F32"; // F32 by default as it is most common
|
|
var DEFAULT_ACCELERATOR = ACCELERATOR_LIST[0].name;
|
|
|
|
// whenever the controller changes, the list of parameters should change
|
|
function onChangeControllerChoice(inst, ui)
|
|
{
|
|
// TODO - update terms to zero when changing from PID to DF types
|
|
// everything hidden by default
|
|
for(var i in config)
|
|
{
|
|
// console.log("ui[config[i].name].hidden=" + ui[config[i].name].hidden)
|
|
ui[config[i].name].hidden = true;
|
|
}
|
|
|
|
// default is to unhide controller choice, precision, and accelerator
|
|
ui.controllerChoice.hidden = false;
|
|
ui.controllerPrecision.hidden = false;
|
|
ui.controllerAccelerator.hidden = true;
|
|
ui.structDisplay.hidden = false;
|
|
|
|
// get the list of elements for this chosen controller
|
|
var control_struct_entry = controller_data.get_control_struct_entry(inst.structDisplay);
|
|
if (control_struct_entry)
|
|
{
|
|
// unhide the long description for this controller
|
|
var longDescName = control_struct_entry["longDescName"];
|
|
ui["longDesc_" + longDescName].hidden=false;
|
|
|
|
var config_entries_list = control_struct_entry["config_entries_list"];
|
|
// unhide the given elements in that list
|
|
for(var e of config_entries_list)
|
|
{
|
|
ui[e[0]].hidden = false;
|
|
inst[e[0]] = e[1];
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
let config = [
|
|
{
|
|
name : "controllerChoice",
|
|
displayName : "Controller/Filter",
|
|
onChange : onChangeControllerChoice,
|
|
description : 'Choice of Controller. NOTE: Changing controller will change all parameters to default.',
|
|
hidden : false,
|
|
default : DEFAULT_CONTROLLER_CHOICE,
|
|
options : CONTROLLER_CHOICE_LIST,
|
|
},
|
|
{
|
|
name : "controllerPrecision",
|
|
displayName : "Precision",
|
|
onChange : onChangeControllerChoice,
|
|
description : 'Choice of Precision. NOTE: Changing precision will change all parameters to default.',
|
|
hidden : false,
|
|
default : DEFAULT_PRECISION,
|
|
options : PRECISION_LIST,
|
|
},
|
|
{
|
|
name : "controllerAccelerator",
|
|
displayName : "Accelerator",
|
|
description : 'Choice of Accelerator.',
|
|
hidden : true,
|
|
default : DEFAULT_ACCELERATOR,
|
|
options : ACCELERATOR_LIST,
|
|
},
|
|
{
|
|
name : "structDisplay",
|
|
displayName : "Controller Structure Chosen",
|
|
description : 'Visualization of the chosen DCL structure.',
|
|
hidden : false,
|
|
getValue : (inst) => {
|
|
var choices_dict = {
|
|
"controller":inst.controllerChoice,
|
|
"precision":inst.controllerPrecision,
|
|
"accelerator":inst.controllerAccelerator,
|
|
};
|
|
return controller_data.get_struct_options(choices_dict).join();
|
|
},
|
|
default : ""
|
|
}
|
|
]
|
|
|
|
function isNumber(s)
|
|
{
|
|
// remove trailing L or f for longs and floats
|
|
if (s.endsWith("L") || s.endsWith("f"))
|
|
{
|
|
s = s.slice(0,-1);
|
|
}
|
|
|
|
// check if the resultant value is a number
|
|
return !isNaN(s);
|
|
}
|
|
|
|
function onValidate(inst, validation) {
|
|
// list the available controlStruct options
|
|
var choices_dict = {
|
|
"controller":inst.controllerChoice,
|
|
"precision":inst.controllerPrecision,
|
|
"accelerator":inst.controllerAccelerator,
|
|
};
|
|
|
|
var availControlStructs = controller_data.get_struct_options(choices_dict);
|
|
if (availControlStructs.length <= 0)
|
|
{
|
|
validation.logError(
|
|
"Precision not available for this controller, please choose a different precision option.",
|
|
inst, "controllerPrecision");
|
|
// validation.logError(
|
|
// "Precision and accelerator combination not available for this controller, please choose a different precision/accelerator option.",
|
|
// inst, "controllerAccelerator");
|
|
}
|
|
var control_struct_entry = controller_data.get_control_struct_entry(inst.structDisplay);
|
|
if (control_struct_entry)
|
|
{
|
|
var config_entries_list = control_struct_entry["config_entries_list"];
|
|
for(var e of config_entries_list)
|
|
{
|
|
// check for empty elements
|
|
if(inst[e[0]] == "")
|
|
{
|
|
validation.logError(
|
|
"A value must be provided.",
|
|
inst, e[0]);
|
|
}
|
|
// check if it's an actual number
|
|
if(!isNumber(inst[e[0]]))
|
|
{
|
|
validation.logError(
|
|
"Value must be a valid number (hex, decimal, float, long, etc.)",
|
|
inst, e[0]
|
|
);
|
|
}
|
|
}
|
|
}
|
|
// only do this check if one of the floating point precisions are chosen
|
|
if (inst.controllerPrecision == "F32" || inst.controllerPrecision == "F64") {
|
|
// check if controllerPrecision matches the precision being used by FPU.js in the "Other Dependencies" section
|
|
var fpuMod = system.modules["/libraries/math/FPU/FPU.js"];
|
|
if(fpuMod)
|
|
{
|
|
if(fpuMod.$static.fpuType.replace("PU","") != inst.controllerPrecision)
|
|
{
|
|
// when controller precision == F64, and the FPU.js file has FPU32 chosen, then warn the user that performance loss will occur
|
|
if (inst.controllerPrecision == "F64" && fpuMod.$static.fpuType == "FPU32") {
|
|
// for devices that can actually support F64, tell user that they can fix the issue
|
|
if (controller_data.fpu64_supported)
|
|
{
|
|
validation.logWarning("Double-precision data type chosen with single-precision floating-point processor chosen. Relatively poor cycle performance should be expected. To improve performance, precision can be updated here or in 'Other Dependencies' below.", inst, "controllerPrecision");
|
|
}
|
|
// for devices that can't support F64, tell the user that performance loss should be expected
|
|
else
|
|
{
|
|
validation.logWarning("Double-precision data type chosen with single-precision floating-point processor chosen. Relatively poor cycle performance should be expected.", inst, "controllerPrecision");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// when controller precision == F32, and the FPU.js file has FPU64 chosen, there should be no issue as FPU64 is backwards compatible with FPU32 instructions and C code
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// verify that TMU1 is enabled if NLPID is chosen
|
|
if (inst.controllerChoice == "NLPID")
|
|
{
|
|
var fpuMod = system.modules["/libraries/math/FPU/FPU.js"];
|
|
if(fpuMod && fpuMod.$static.tmuType != "TMU1")
|
|
{
|
|
validation.logError("TMU1 must be enabled to use NLPID controller. Update 'Other Dependencies' below to enable TMU1.", inst, "controllerChoice");
|
|
}
|
|
}
|
|
}
|
|
|
|
// Choose which controllerChoice to have its parameters be unhidden by default
|
|
controller_data.set_config_entries_default_unhidden(DEFAULT_CONTROLLER_CHOICE)
|
|
// add on all the long description config entries for each controller
|
|
config = config.concat(controller_data.getLongDescriptionConfigEntries(DEFAULT_CONTROLLER_CHOICE));
|
|
// add on all the config_entries from controller_data.js to "config" array
|
|
config = config.concat(controller_data.get_config_entries_list());
|
|
|
|
var longDescription = `The DCL contains the following controller types:
|
|
* Linear PID
|
|
* Linear PI
|
|
* Non-linear PID
|
|
* Non-linear PI
|
|
* Double Integrator
|
|
* Direct Form 1 (first order)
|
|
* Direct Form 1 (third order)
|
|
* Direct Form 2 (second order)
|
|
* Direct Form 2 (third order)
|
|
|
|
See the DCL User's Guide for details on each controller/compensator and its variables:
|
|
|
|
[Digital Control Library User's Guide](https://dev.ti.com/tirex/explore/node?node=AKZRbh4oxv98HaO0YKjygQ__gYkahfz__LATEST)`
|
|
|
|
var controllerModule = {
|
|
c2000wareLibraryName: "CONTROLLER",
|
|
displayName: "CONTROLLER",
|
|
defaultInstanceName: "myCONTROLLER",
|
|
description: "CONTROLLER",
|
|
longDescription: longDescription,
|
|
config: config,
|
|
references : [],
|
|
templates: {
|
|
c2000ware_libraries_c : "/libraries/control/dcl/templates/controller.c2000ware_libraries.c.xdt",
|
|
c2000ware_libraries_h : "/libraries/control/dcl/templates/controller.c2000ware_libraries.h.xdt",
|
|
},
|
|
validate : onValidate,
|
|
modules: (inst) => {
|
|
var mods = [];
|
|
var refFilesArr = controller_data.getRefFilesModuleArrFromControlStruct(inst.structDisplay);
|
|
mods = refFilesArr;
|
|
return mods;
|
|
}
|
|
};
|
|
|
|
exports = controllerModule; |