@jetta/axle-load-calculator 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (392) hide show
  1. package/.cursor/ai_changelog/INDEX.md +13 -0
  2. package/.cursor/ai_changelog/_TEMPLATE.md +55 -0
  3. package/.cursor/rules/code-standards.mdc +103 -0
  4. package/.cursor/rules/knowledge-base.mdc +14 -0
  5. package/.cursor/rules/planning-standards.mdc +55 -0
  6. package/.cursor/skills/document-feature-knowledge/SKILL.md +51 -0
  7. package/README.md +49 -0
  8. package/bitbucket-pipelines.yml +81 -0
  9. package/build/core/contracts/chassi_reference.d.ts +7 -0
  10. package/build/core/contracts/chassi_reference.d.ts.map +1 -0
  11. package/build/core/contracts/chassi_reference.js +5 -0
  12. package/build/core/contracts/ms_faixas_contract.d.ts +13 -0
  13. package/build/core/contracts/ms_faixas_contract.d.ts.map +1 -0
  14. package/build/core/contracts/ms_faixas_contract.js +89 -0
  15. package/build/core/contracts/rotation_enum.d.ts +11 -0
  16. package/build/core/contracts/rotation_enum.d.ts.map +1 -0
  17. package/build/core/contracts/rotation_enum.js +9 -0
  18. package/build/core/contracts/suspension_type.d.ts +5 -0
  19. package/build/core/contracts/suspension_type.d.ts.map +1 -0
  20. package/build/core/contracts/suspension_type.js +4 -0
  21. package/build/core/contracts/transport_record.d.ts +5 -0
  22. package/build/core/contracts/transport_record.d.ts.map +1 -0
  23. package/build/core/contracts/transport_record.js +1 -0
  24. package/build/core/contracts/vehicle_type.d.ts +12 -0
  25. package/build/core/contracts/vehicle_type.d.ts.map +1 -0
  26. package/build/core/contracts/vehicle_type.js +10 -0
  27. package/build/core/contracts/vehicle_version.d.ts +8 -0
  28. package/build/core/contracts/vehicle_version.d.ts.map +1 -0
  29. package/build/core/contracts/vehicle_version.js +7 -0
  30. package/build/core/contracts/wire_flags.d.ts +27 -0
  31. package/build/core/contracts/wire_flags.d.ts.map +1 -0
  32. package/build/core/contracts/wire_flags.js +26 -0
  33. package/build/core/math/float_tools.d.ts +7 -0
  34. package/build/core/math/float_tools.d.ts.map +1 -0
  35. package/build/core/math/float_tools.js +14 -0
  36. package/build/core/math/gaussian_elimination.d.ts +8 -0
  37. package/build/core/math/gaussian_elimination.d.ts.map +1 -0
  38. package/build/core/math/gaussian_elimination.js +85 -0
  39. package/build/core/orchestration/axle_weight_physics.d.ts +7 -0
  40. package/build/core/orchestration/axle_weight_physics.d.ts.map +1 -0
  41. package/build/core/orchestration/axle_weight_physics.js +27 -0
  42. package/build/core/orchestration/collision_checker.d.ts +6 -0
  43. package/build/core/orchestration/collision_checker.d.ts.map +1 -0
  44. package/build/core/orchestration/collision_checker.js +67 -0
  45. package/build/core/orchestration/connector_payload_builder.d.ts +11 -0
  46. package/build/core/orchestration/connector_payload_builder.d.ts.map +1 -0
  47. package/build/core/orchestration/connector_payload_builder.js +67 -0
  48. package/build/core/orchestration/java_mass_center.d.ts +9 -0
  49. package/build/core/orchestration/java_mass_center.d.ts.map +1 -0
  50. package/build/core/orchestration/java_mass_center.js +79 -0
  51. package/build/core/orchestration/output_builder.d.ts +11 -0
  52. package/build/core/orchestration/output_builder.d.ts.map +1 -0
  53. package/build/core/orchestration/output_builder.js +15 -0
  54. package/build/core/orchestration/request_schema.d.ts +65 -0
  55. package/build/core/orchestration/request_schema.d.ts.map +1 -0
  56. package/build/core/orchestration/request_schema.js +20 -0
  57. package/build/core/orchestration/weight_by_axis_task.d.ts +7 -0
  58. package/build/core/orchestration/weight_by_axis_task.d.ts.map +1 -0
  59. package/build/core/orchestration/weight_by_axis_task.js +105 -0
  60. package/build/core/physics/items/allocated_item.d.ts +22 -0
  61. package/build/core/physics/items/allocated_item.d.ts.map +1 -0
  62. package/build/core/physics/items/allocated_item.js +29 -0
  63. package/build/core/physics/items/allocated_item_manager.d.ts +31 -0
  64. package/build/core/physics/items/allocated_item_manager.d.ts.map +1 -0
  65. package/build/core/physics/items/allocated_item_manager.js +38 -0
  66. package/build/core/physics/items/center_of_mass.d.ts +14 -0
  67. package/build/core/physics/items/center_of_mass.d.ts.map +1 -0
  68. package/build/core/physics/items/center_of_mass.js +24 -0
  69. package/build/core/physics/items/compute_grouper_center_of_mass.d.ts +19 -0
  70. package/build/core/physics/items/compute_grouper_center_of_mass.d.ts.map +1 -0
  71. package/build/core/physics/items/compute_grouper_center_of_mass.js +28 -0
  72. package/build/core/physics/items/item_templates.d.ts +32 -0
  73. package/build/core/physics/items/item_templates.d.ts.map +1 -0
  74. package/build/core/physics/items/item_templates.js +53 -0
  75. package/build/core/physics/items/multi_container_allocated_items.d.ts +37 -0
  76. package/build/core/physics/items/multi_container_allocated_items.d.ts.map +1 -0
  77. package/build/core/physics/items/multi_container_allocated_items.js +91 -0
  78. package/build/core/physics/items/rotation_transforms.d.ts +8 -0
  79. package/build/core/physics/items/rotation_transforms.d.ts.map +1 -0
  80. package/build/core/physics/items/rotation_transforms.js +21 -0
  81. package/build/core/physics/models/axle_weight_model.d.ts +32 -0
  82. package/build/core/physics/models/axle_weight_model.d.ts.map +1 -0
  83. package/build/core/physics/models/axle_weight_model.js +72 -0
  84. package/build/core/physics/models/bi_truck_model.d.ts +21 -0
  85. package/build/core/physics/models/bi_truck_model.d.ts.map +1 -0
  86. package/build/core/physics/models/bi_truck_model.js +60 -0
  87. package/build/core/physics/models/bi_truck_tractor_semi_trailer_model.d.ts +21 -0
  88. package/build/core/physics/models/bi_truck_tractor_semi_trailer_model.d.ts.map +1 -0
  89. package/build/core/physics/models/bi_truck_tractor_semi_trailer_model.js +69 -0
  90. package/build/core/physics/models/bitrem_model.d.ts +33 -0
  91. package/build/core/physics/models/bitrem_model.d.ts.map +1 -0
  92. package/build/core/physics/models/bitrem_model.js +123 -0
  93. package/build/core/physics/models/chassi_forces.d.ts +30 -0
  94. package/build/core/physics/models/chassi_forces.d.ts.map +1 -0
  95. package/build/core/physics/models/chassi_forces.js +39 -0
  96. package/build/core/physics/models/deflection/beam_deflection.d.ts +28 -0
  97. package/build/core/physics/models/deflection/beam_deflection.d.ts.map +1 -0
  98. package/build/core/physics/models/deflection/beam_deflection.js +78 -0
  99. package/build/core/physics/models/deflection/bitrem_deflection.d.ts +22 -0
  100. package/build/core/physics/models/deflection/bitrem_deflection.d.ts.map +1 -0
  101. package/build/core/physics/models/deflection/bitrem_deflection.js +54 -0
  102. package/build/core/physics/models/deflection/create_deflection_delegate.d.ts +12 -0
  103. package/build/core/physics/models/deflection/create_deflection_delegate.d.ts.map +1 -0
  104. package/build/core/physics/models/deflection/create_deflection_delegate.js +32 -0
  105. package/build/core/physics/models/deflection/deflection_model.d.ts +19 -0
  106. package/build/core/physics/models/deflection/deflection_model.d.ts.map +1 -0
  107. package/build/core/physics/models/deflection/deflection_model.js +23 -0
  108. package/build/core/physics/models/deflection/deflection_support_manager.d.ts +21 -0
  109. package/build/core/physics/models/deflection/deflection_support_manager.d.ts.map +1 -0
  110. package/build/core/physics/models/deflection/deflection_support_manager.js +40 -0
  111. package/build/core/physics/models/deflection/deflection_tools.d.ts +6 -0
  112. package/build/core/physics/models/deflection/deflection_tools.d.ts.map +1 -0
  113. package/build/core/physics/models/deflection/deflection_tools.js +10 -0
  114. package/build/core/physics/models/deflection/integration_constant_calculator.d.ts +22 -0
  115. package/build/core/physics/models/deflection/integration_constant_calculator.d.ts.map +1 -0
  116. package/build/core/physics/models/deflection/integration_constant_calculator.js +48 -0
  117. package/build/core/physics/models/deflection/rodotrem_deflection.d.ts +22 -0
  118. package/build/core/physics/models/deflection/rodotrem_deflection.d.ts.map +1 -0
  119. package/build/core/physics/models/deflection/rodotrem_deflection.js +47 -0
  120. package/build/core/physics/models/deflection/semi_reboque_deflection.d.ts +21 -0
  121. package/build/core/physics/models/deflection/semi_reboque_deflection.d.ts.map +1 -0
  122. package/build/core/physics/models/deflection/semi_reboque_deflection.js +31 -0
  123. package/build/core/physics/models/deflection/simple_truck_deflection.d.ts +20 -0
  124. package/build/core/physics/models/deflection/simple_truck_deflection.d.ts.map +1 -0
  125. package/build/core/physics/models/deflection/simple_truck_deflection.js +28 -0
  126. package/build/core/physics/models/deflection/vanderleia_deflection.d.ts +21 -0
  127. package/build/core/physics/models/deflection/vanderleia_deflection.d.ts.map +1 -0
  128. package/build/core/physics/models/deflection/vanderleia_deflection.js +41 -0
  129. package/build/core/physics/models/old_tare_model.d.ts +17 -0
  130. package/build/core/physics/models/old_tare_model.d.ts.map +1 -0
  131. package/build/core/physics/models/old_tare_model.js +40 -0
  132. package/build/core/physics/models/old_tare_scale.d.ts +7 -0
  133. package/build/core/physics/models/old_tare_scale.d.ts.map +1 -0
  134. package/build/core/physics/models/old_tare_scale.js +8 -0
  135. package/build/core/physics/models/old_tare_semireboque.d.ts +7 -0
  136. package/build/core/physics/models/old_tare_semireboque.d.ts.map +1 -0
  137. package/build/core/physics/models/old_tare_semireboque.js +37 -0
  138. package/build/core/physics/models/old_tare_truck.d.ts +7 -0
  139. package/build/core/physics/models/old_tare_truck.d.ts.map +1 -0
  140. package/build/core/physics/models/old_tare_truck.js +12 -0
  141. package/build/core/physics/models/old_tare_vanderleia.d.ts +7 -0
  142. package/build/core/physics/models/old_tare_vanderleia.d.ts.map +1 -0
  143. package/build/core/physics/models/old_tare_vanderleia.js +31 -0
  144. package/build/core/physics/models/percentage_on_axles_calculator.d.ts +19 -0
  145. package/build/core/physics/models/percentage_on_axles_calculator.d.ts.map +1 -0
  146. package/build/core/physics/models/percentage_on_axles_calculator.js +39 -0
  147. package/build/core/physics/models/quad_semi_trailer_model.d.ts +21 -0
  148. package/build/core/physics/models/quad_semi_trailer_model.d.ts.map +1 -0
  149. package/build/core/physics/models/quad_semi_trailer_model.js +70 -0
  150. package/build/core/physics/models/rodotrem_model.d.ts +33 -0
  151. package/build/core/physics/models/rodotrem_model.d.ts.map +1 -0
  152. package/build/core/physics/models/rodotrem_model.js +101 -0
  153. package/build/core/physics/models/semi_reboque_base.d.ts +34 -0
  154. package/build/core/physics/models/semi_reboque_base.d.ts.map +1 -0
  155. package/build/core/physics/models/semi_reboque_base.js +85 -0
  156. package/build/core/physics/models/semi_reboque_model.d.ts +41 -0
  157. package/build/core/physics/models/semi_reboque_model.d.ts.map +1 -0
  158. package/build/core/physics/models/semi_reboque_model.js +84 -0
  159. package/build/core/physics/models/simple_truck_base.d.ts +29 -0
  160. package/build/core/physics/models/simple_truck_base.d.ts.map +1 -0
  161. package/build/core/physics/models/simple_truck_base.js +57 -0
  162. package/build/core/physics/models/simple_truck_model.d.ts +41 -0
  163. package/build/core/physics/models/simple_truck_model.d.ts.map +1 -0
  164. package/build/core/physics/models/simple_truck_model.js +76 -0
  165. package/build/core/physics/models/single_container_tare.d.ts +18 -0
  166. package/build/core/physics/models/single_container_tare.d.ts.map +1 -0
  167. package/build/core/physics/models/single_container_tare.js +45 -0
  168. package/build/core/physics/models/tare_model.d.ts +12 -0
  169. package/build/core/physics/models/tare_model.d.ts.map +1 -0
  170. package/build/core/physics/models/tare_model.js +36 -0
  171. package/build/core/physics/models/vanderleia_model.d.ts +33 -0
  172. package/build/core/physics/models/vanderleia_model.d.ts.map +1 -0
  173. package/build/core/physics/models/vanderleia_model.js +100 -0
  174. package/build/core/physics/services/axle_weight_output_builder.d.ts +27 -0
  175. package/build/core/physics/services/axle_weight_output_builder.d.ts.map +1 -0
  176. package/build/core/physics/services/axle_weight_output_builder.js +42 -0
  177. package/build/core/physics/services/axle_weight_service.d.ts +20 -0
  178. package/build/core/physics/services/axle_weight_service.d.ts.map +1 -0
  179. package/build/core/physics/services/axle_weight_service.js +91 -0
  180. package/build/core/physics/services/cm_axle_weight_service.d.ts +12 -0
  181. package/build/core/physics/services/cm_axle_weight_service.d.ts.map +1 -0
  182. package/build/core/physics/services/cm_axle_weight_service.js +33 -0
  183. package/build/core/physics/services/container_corner_forces.d.ts +33 -0
  184. package/build/core/physics/services/container_corner_forces.d.ts.map +1 -0
  185. package/build/core/physics/services/container_corner_forces.js +84 -0
  186. package/build/core/physics/transports/axle_manager.d.ts +22 -0
  187. package/build/core/physics/transports/axle_manager.d.ts.map +1 -0
  188. package/build/core/physics/transports/axle_manager.js +34 -0
  189. package/build/core/physics/transports/axle_record.d.ts +21 -0
  190. package/build/core/physics/transports/axle_record.d.ts.map +1 -0
  191. package/build/core/physics/transports/axle_record.js +57 -0
  192. package/build/core/physics/transports/chassi.d.ts +52 -0
  193. package/build/core/physics/transports/chassi.d.ts.map +1 -0
  194. package/build/core/physics/transports/chassi.js +105 -0
  195. package/build/core/physics/transports/container_record.d.ts +25 -0
  196. package/build/core/physics/transports/container_record.d.ts.map +1 -0
  197. package/build/core/physics/transports/container_record.js +49 -0
  198. package/build/core/physics/transports/containerweight/container_max_weight_calculator.d.ts +27 -0
  199. package/build/core/physics/transports/containerweight/container_max_weight_calculator.d.ts.map +1 -0
  200. package/build/core/physics/transports/containerweight/container_max_weight_calculator.js +40 -0
  201. package/build/core/physics/transports/containerweight/container_tare_calculator.d.ts +28 -0
  202. package/build/core/physics/transports/containerweight/container_tare_calculator.d.ts.map +1 -0
  203. package/build/core/physics/transports/containerweight/container_tare_calculator.js +55 -0
  204. package/build/core/physics/transports/containerweight/container_weight_model.d.ts +15 -0
  205. package/build/core/physics/transports/containerweight/container_weight_model.d.ts.map +1 -0
  206. package/build/core/physics/transports/containerweight/container_weight_model.js +31 -0
  207. package/build/core/physics/transports/containerweight/merged_containers_weight_calculator.d.ts +17 -0
  208. package/build/core/physics/transports/containerweight/merged_containers_weight_calculator.d.ts.map +1 -0
  209. package/build/core/physics/transports/containerweight/merged_containers_weight_calculator.js +31 -0
  210. package/build/core/physics/transports/containerweight/single_container_weight_calculator.d.ts +20 -0
  211. package/build/core/physics/transports/containerweight/single_container_weight_calculator.d.ts.map +1 -0
  212. package/build/core/physics/transports/containerweight/single_container_weight_calculator.js +48 -0
  213. package/build/core/physics/transports/grouped_containers.d.ts +34 -0
  214. package/build/core/physics/transports/grouped_containers.d.ts.map +1 -0
  215. package/build/core/physics/transports/grouped_containers.js +68 -0
  216. package/build/core/physics/transports/merged_containers.d.ts +26 -0
  217. package/build/core/physics/transports/merged_containers.d.ts.map +1 -0
  218. package/build/core/physics/transports/merged_containers.js +45 -0
  219. package/build/core/physics/transports/tare/bitrem_axle_splitter.d.ts +26 -0
  220. package/build/core/physics/transports/tare/bitrem_axle_splitter.d.ts.map +1 -0
  221. package/build/core/physics/transports/tare/bitrem_axle_splitter.js +84 -0
  222. package/build/core/physics/transports/tare/bitrem_axle_weight_split.d.ts +22 -0
  223. package/build/core/physics/transports/tare/bitrem_axle_weight_split.d.ts.map +1 -0
  224. package/build/core/physics/transports/tare/bitrem_axle_weight_split.js +32 -0
  225. package/build/core/physics/transports/transport.d.ts +33 -0
  226. package/build/core/physics/transports/transport.d.ts.map +1 -0
  227. package/build/core/physics/transports/transport.js +110 -0
  228. package/build/index.d.ts +8 -0
  229. package/build/index.d.ts.map +1 -0
  230. package/build/index.js +10 -0
  231. package/eslint.config.js +51 -0
  232. package/package.json +38 -0
  233. package/src/core/contracts/chassi_reference.ts +7 -0
  234. package/src/core/contracts/ms_faixas_contract.ts +114 -0
  235. package/src/core/contracts/rotation_enum.ts +11 -0
  236. package/src/core/contracts/suspension_type.ts +4 -0
  237. package/src/core/contracts/transport_record.ts +4 -0
  238. package/src/core/contracts/vehicle_type.ts +12 -0
  239. package/src/core/contracts/vehicle_version.ts +7 -0
  240. package/src/core/contracts/wire_flags.ts +26 -0
  241. package/src/core/math/float_tools.ts +17 -0
  242. package/src/core/math/gaussian_elimination.ts +104 -0
  243. package/src/core/orchestration/axle_weight_physics.ts +37 -0
  244. package/src/core/orchestration/collision_checker.ts +86 -0
  245. package/src/core/orchestration/connector_payload_builder.ts +81 -0
  246. package/src/core/orchestration/java_mass_center.ts +98 -0
  247. package/src/core/orchestration/output_builder.ts +18 -0
  248. package/src/core/orchestration/request_schema.ts +26 -0
  249. package/src/core/orchestration/weight_by_axis_task.ts +140 -0
  250. package/src/core/physics/items/allocated_item.ts +41 -0
  251. package/src/core/physics/items/allocated_item_manager.ts +50 -0
  252. package/src/core/physics/items/center_of_mass.ts +31 -0
  253. package/src/core/physics/items/compute_grouper_center_of_mass.ts +44 -0
  254. package/src/core/physics/items/item_templates.ts +65 -0
  255. package/src/core/physics/items/multi_container_allocated_items.ts +120 -0
  256. package/src/core/physics/items/rotation_transforms.ts +29 -0
  257. package/src/core/physics/models/axle_weight_model.ts +109 -0
  258. package/src/core/physics/models/bi_truck_model.ts +74 -0
  259. package/src/core/physics/models/bi_truck_tractor_semi_trailer_model.ts +86 -0
  260. package/src/core/physics/models/bitrem_model.ts +148 -0
  261. package/src/core/physics/models/chassi_forces.ts +50 -0
  262. package/src/core/physics/models/deflection/beam_deflection.ts +105 -0
  263. package/src/core/physics/models/deflection/bitrem_deflection.ts +68 -0
  264. package/src/core/physics/models/deflection/create_deflection_delegate.ts +46 -0
  265. package/src/core/physics/models/deflection/deflection_model.ts +33 -0
  266. package/src/core/physics/models/deflection/deflection_support_manager.ts +56 -0
  267. package/src/core/physics/models/deflection/deflection_tools.ts +11 -0
  268. package/src/core/physics/models/deflection/integration_constant_calculator.ts +62 -0
  269. package/src/core/physics/models/deflection/rodotrem_deflection.ts +57 -0
  270. package/src/core/physics/models/deflection/semi_reboque_deflection.ts +40 -0
  271. package/src/core/physics/models/deflection/simple_truck_deflection.ts +35 -0
  272. package/src/core/physics/models/deflection/vanderleia_deflection.ts +48 -0
  273. package/src/core/physics/models/old_tare_model.ts +51 -0
  274. package/src/core/physics/models/old_tare_scale.ts +9 -0
  275. package/src/core/physics/models/old_tare_semireboque.ts +51 -0
  276. package/src/core/physics/models/old_tare_truck.ts +15 -0
  277. package/src/core/physics/models/old_tare_vanderleia.ts +44 -0
  278. package/src/core/physics/models/percentage_on_axles_calculator.ts +49 -0
  279. package/src/core/physics/models/quad_semi_trailer_model.ts +87 -0
  280. package/src/core/physics/models/rodotrem_model.ts +131 -0
  281. package/src/core/physics/models/semi_reboque_base.ts +103 -0
  282. package/src/core/physics/models/semi_reboque_model.ts +127 -0
  283. package/src/core/physics/models/simple_truck_base.ts +70 -0
  284. package/src/core/physics/models/simple_truck_model.ts +115 -0
  285. package/src/core/physics/models/single_container_tare.ts +56 -0
  286. package/src/core/physics/models/tare_model.ts +46 -0
  287. package/src/core/physics/models/vanderleia_model.ts +125 -0
  288. package/src/core/physics/services/axle_weight_output_builder.ts +63 -0
  289. package/src/core/physics/services/axle_weight_service.ts +116 -0
  290. package/src/core/physics/services/cm_axle_weight_service.ts +45 -0
  291. package/src/core/physics/services/container_corner_forces.ts +95 -0
  292. package/src/core/physics/transports/axle_manager.ts +45 -0
  293. package/src/core/physics/transports/axle_record.ts +68 -0
  294. package/src/core/physics/transports/chassi.ts +130 -0
  295. package/src/core/physics/transports/container_record.ts +58 -0
  296. package/src/core/physics/transports/containerweight/container_max_weight_calculator.ts +59 -0
  297. package/src/core/physics/transports/containerweight/container_tare_calculator.ts +76 -0
  298. package/src/core/physics/transports/containerweight/container_weight_model.ts +38 -0
  299. package/src/core/physics/transports/containerweight/merged_containers_weight_calculator.ts +39 -0
  300. package/src/core/physics/transports/containerweight/single_container_weight_calculator.ts +65 -0
  301. package/src/core/physics/transports/grouped_containers.ts +91 -0
  302. package/src/core/physics/transports/merged_containers.ts +62 -0
  303. package/src/core/physics/transports/tare/bitrem_axle_splitter.ts +107 -0
  304. package/src/core/physics/transports/tare/bitrem_axle_weight_split.ts +55 -0
  305. package/src/core/physics/transports/transport.ts +137 -0
  306. package/src/index.ts +12 -0
  307. package/src/service/.gitkeep +0 -0
  308. package/test/data/src/core/orchestration/weight_by_axis/case_1_basic_truck_input.json +1759 -0
  309. package/test/data/src/core/orchestration/weight_by_axis/case_2_vanderleia_input.json +1286 -0
  310. package/test/data/src/core/orchestration/weight_by_axis/case_3_interlink_input.json +2226 -0
  311. package/test/data/src/core/orchestration/weight_by_axis/case_4_quad_semi_trailer.json +639 -0
  312. package/test/data/src/core/orchestration/weight_by_axis/case_5_custom_center_of_gravity.json +557 -0
  313. package/test/data/src/core/physics/axle_weight_calculations/case_2_bitruck.json +664 -0
  314. package/test/data/src/core/physics/axle_weight_calculations/case_4_quad_semi_trailer.json +674 -0
  315. package/test/data/src/core/physics/axle_weight_calculations/case_5_bi_truck_semi_trailer.json +674 -0
  316. package/test/data/src/core/physics/axle_weight_service/case_1_input_truck.json +1025 -0
  317. package/test/data/src/core/physics/axle_weight_service/case_1_output_truck.json +38 -0
  318. package/test/data/src/core/physics/axle_weight_service/case_2_vanderleia_input.json +1286 -0
  319. package/test/data/src/core/physics/axle_weight_service/case_2_vanderleia_output.json +65 -0
  320. package/test/data/src/core/physics/axle_weight_service/case_3_input_semireboque.json +24625 -0
  321. package/test/data/src/core/physics/axle_weight_service/case_3_output_semireboque.json +57 -0
  322. package/test/data/src/core/physics/axle_weight_service/case_4_input_bitrem.json +2226 -0
  323. package/test/data/src/core/physics/axle_weight_service/case_4_output_bitrem.json +96 -0
  324. package/test/data/src/core/physics/beam_deflection/case_10_rodotrem_offset.json +474 -0
  325. package/test/data/src/core/physics/beam_deflection/case_11_bitruck.json +664 -0
  326. package/test/data/src/core/physics/beam_deflection/case_12_quad_semi_trailer.json +792 -0
  327. package/test/data/src/core/physics/beam_deflection/case_13_bi_truck_semi_trailer.json +792 -0
  328. package/test/data/src/core/physics/beam_deflection/case_1_documentation.ipynb +316 -0
  329. package/test/data/src/core/physics/beam_deflection/case_1_semireboque.json +402 -0
  330. package/test/data/src/core/physics/beam_deflection/case_2_bitrem.json +434 -0
  331. package/test/data/src/core/physics/beam_deflection/case_3_rodotrem.json +474 -0
  332. package/test/data/src/core/physics/beam_deflection/case_4_vanderleia_pneumatica.json +425 -0
  333. package/test/data/src/core/physics/beam_deflection/case_5_vanderleia_mecanica.json +366 -0
  334. package/test/data/src/core/physics/beam_deflection/case_6_truck.json +279 -0
  335. package/test/data/src/core/physics/beam_deflection/case_7_semireboque_structural_offset.json +318 -0
  336. package/test/data/src/core/physics/beam_deflection/case_8_vanderleia_offset.json +425 -0
  337. package/test/data/src/core/physics/beam_deflection/case_9_bitrem_offset.json +434 -0
  338. package/test/data/src/core/physics/bitrem_axle_splitter/case_1_simple_bitrem.json +145 -0
  339. package/test/data/src/core/physics/bitrem_axle_splitter/case_2_lowered_bitrem.json +238 -0
  340. package/test/data/src/core/physics/bitrem_axle_splitter/case_3_lowered_positive_proportion.json +238 -0
  341. package/test/data/src/core/physics/c_m_axle_weight_service/case_1_interlink_trailer.json +94 -0
  342. package/test/data/src/core/physics/calculations/case_1_simple_truck.json +83 -0
  343. package/test/data/src/core/physics/calculations/case_2_lowered_bitrem.json +1051 -0
  344. package/test/data/src/core/physics/calculations/case_3_container_mercedes.json +50 -0
  345. package/test/data/src/core/physics/container_corner_forces/case_1.json +674 -0
  346. package/test/data/src/core/physics/container_weight/case_1_basictruck.json +223 -0
  347. package/test/data/src/core/physics/container_weight/case_2_roadtrain.json +277 -0
  348. package/test/data/src/core/physics/container_weight/case_3_semireboque_rebaixado.json +197 -0
  349. package/test/data/src/core/physics/container_weight/case_4_semireboque_neck_limit.json +197 -0
  350. package/test/data/src/core/physics/container_weight/case_5_vanderleia_rebaixada.json +211 -0
  351. package/test/data/src/core/physics/container_weight/case_6_lowered_interlink.json +230 -0
  352. package/test/data/src/core/physics/python_goldens.json +9 -0
  353. package/test/data/src/core/physics/tare/case_1_simple_vanderleia.json +185 -0
  354. package/test/data/src/core/physics/tare/case_2_lowered_vanderleia.json +646 -0
  355. package/test/data/src/core/physics/tare/case_3_lowered_interlink.json +230 -0
  356. package/test/data/src/core/physics/tare/case_4_negative_tare_VUC.json +483 -0
  357. package/test/data/src/core/physics/tare/case_5_truck_bitruck.json +664 -0
  358. package/test/data/src/core/physics/tare/case_6_quad_semi_trailer.json +203 -0
  359. package/test/data/src/core/physics/tare/case_7_bi_truck_semi_trailer.json +203 -0
  360. package/test/data/src/core/physics/tare/case_8_triaxle_semi_trailer.json +203 -0
  361. package/test/data/src/core/physics/time_performance/case_1_center_of_mass.json +2916 -0
  362. package/test/data/src/core/physics/trucks/bitrem.json +150 -0
  363. package/test/data/src/core/physics/trucks/lowered_bitrem.json +1216 -0
  364. package/test/data/src/core/physics/trucks/lowered_bitrem_empty_first_container.json +1182 -0
  365. package/test/data/src/core/physics/trucks/rodotrem.json +148 -0
  366. package/test/data/src/core/physics/trucks/semi_reboque.json +91 -0
  367. package/test/data/src/core/physics/trucks/semi_reboque_rebaixado.json +1629 -0
  368. package/test/data/src/core/physics/trucks/simple_truck.json +85 -0
  369. package/test/data/src/core/physics/trucks/vanderleia_mechanical.json +105 -0
  370. package/test/data/src/core/physics/trucks/vanderleia_pneumatic.json +105 -0
  371. package/test/src/core/orchestration/request_schema.test.ts +20 -0
  372. package/test/src/core/orchestration/weight_by_axis_task.test.ts +87 -0
  373. package/test/src/core/physics/items/center_of_mass.test.ts +38 -0
  374. package/test/src/core/physics/items/multi_container_allocated_items.test.ts +22 -0
  375. package/test/src/core/physics/math_input_helpers.ts +64 -0
  376. package/test/src/core/physics/models/bitrem_model.test.ts +54 -0
  377. package/test/src/core/physics/models/deflection/deflection_model.test.ts +78 -0
  378. package/test/src/core/physics/models/rodotrem_model.test.ts +29 -0
  379. package/test/src/core/physics/models/semi_reboque_model.test.ts +72 -0
  380. package/test/src/core/physics/models/simple_truck_model.test.ts +23 -0
  381. package/test/src/core/physics/models/tare_model.test.ts +34 -0
  382. package/test/src/core/physics/models/vanderleia_model.test.ts +36 -0
  383. package/test/src/core/physics/services/axle_weight_service.test.ts +56 -0
  384. package/test/src/core/physics/services/cm_axle_weight_service.test.ts +23 -0
  385. package/test/src/core/physics/services/container_corner_forces.test.ts +23 -0
  386. package/test/src/core/physics/test_helpers.ts +13 -0
  387. package/test/src/core/physics/transports/chassi.test.ts +35 -0
  388. package/test/src/core/physics/transports/containerweight/container_weight_model.test.ts +57 -0
  389. package/test/src/core/physics/transports/tare/bitrem_axle_splitter.test.ts +30 -0
  390. package/test/src/index.test.ts +35 -0
  391. package/tsconfig.eslint.json +15 -0
  392. package/tsconfig.json +19 -0
@@ -0,0 +1,65 @@
1
+ import type { RotationCode } from '../../contracts/rotation_enum.js'
2
+ import { ROTATION } from '../../contracts/rotation_enum.js'
3
+ import { rotate_dimensions } from './rotation_transforms.js'
4
+
5
+ /**
6
+ * Item dimensions and weights keyed by template index.
7
+ */
8
+ export class ItemTemplates
9
+ {
10
+ ids: string[] = []
11
+ weights: number[] = []
12
+ lengths: number[] = []
13
+ widths: number[] = []
14
+ heights: number[] = []
15
+ private dimensions: [number, number, number][] = []
16
+
17
+ /**
18
+ * @param item_id - Template id string.
19
+ * @returns Template index.
20
+ */
21
+ index_of(item_id: string): number
22
+ {
23
+ const index = this.ids.indexOf(item_id)
24
+ if (index < 0)
25
+ {
26
+ throw new Error(`Unknown item id ${item_id}`)
27
+ }
28
+ return index
29
+ }
30
+
31
+ /**
32
+ * @param item_data - Ms-faixas or math input item definition.
33
+ */
34
+ add_template_from_item_data(item_data: Record<string, unknown>): void
35
+ {
36
+ const id = String(item_data.id ?? item_data._id)
37
+ this.ids.push(id)
38
+ this.weights.push(Number(item_data.peso ?? item_data.weight ?? 0))
39
+ const width = Number(item_data.largura ?? item_data.width ?? 0)
40
+ const length = Number(item_data.comprimento ?? item_data.length ?? 0)
41
+ const height = Number(item_data.altura ?? item_data.height ?? 0)
42
+ this.widths.push(width)
43
+ this.lengths.push(length)
44
+ this.heights.push(height)
45
+ this.dimensions.push([width, length, height])
46
+ }
47
+
48
+ /**
49
+ * @param template_index - Template index.
50
+ * @param rotation - Rotation code.
51
+ * @returns Length along chassis z for rotation.
52
+ */
53
+ get_length(template_index: number, rotation: RotationCode = ROTATION.POS1): number
54
+ {
55
+ return rotate_dimensions(rotation, this.dimensions[template_index])[1]
56
+ }
57
+
58
+ /**
59
+ * @param item_data - Math input item row.
60
+ */
61
+ add_template_from_math_item(item_data: Record<string, unknown>): void
62
+ {
63
+ this.add_template_from_item_data(item_data)
64
+ }
65
+ }
@@ -0,0 +1,120 @@
1
+ import type { MergedContainers } from '../transports/merged_containers.js'
2
+ import { AllocatedItem } from './allocated_item.js'
3
+ import { AllocatedItemManager } from './allocated_item_manager.js'
4
+ import type { ItemTemplates } from './item_templates.js'
5
+
6
+ /**
7
+ * Allocated items grouped by container sequence and merged by grouper.
8
+ */
9
+ export class MultiContainerAllocatedItems
10
+ {
11
+ allocated_items_by_sequence_index: Record<number, AllocatedItemManager>
12
+ allocated_items_by_grouper_index: Record<number, AllocatedItemManager> = {}
13
+
14
+ /**
15
+ * @param allocated_items_by_sequence_index - Items per container sequence.
16
+ */
17
+ constructor(allocated_items_by_sequence_index: Record<number, AllocatedItemManager>)
18
+ {
19
+ this.allocated_items_by_sequence_index = allocated_items_by_sequence_index
20
+ }
21
+
22
+ /**
23
+ * @param sequence_index - Container sequence id.
24
+ * @returns Manager for sequence.
25
+ */
26
+ get_allocated_items_by_sequence_index(sequence_index: number): AllocatedItemManager
27
+ {
28
+ return this.allocated_items_by_sequence_index[sequence_index]
29
+ }
30
+
31
+ /**
32
+ * @param grouper_index - Grouper id.
33
+ * @returns Manager for grouper.
34
+ */
35
+ get_allocated_items_by_grouper_index(grouper_index: number): AllocatedItemManager
36
+ {
37
+ return this.allocated_items_by_grouper_index[grouper_index]
38
+ }
39
+
40
+ /**
41
+ * @param grouper_index_list - Grouper ids to initialize.
42
+ */
43
+ create_allocated_items_by_grouper(grouper_index_list: number[]): void
44
+ {
45
+ const templates = this.get_item_templates()
46
+ for (const grouper_index of grouper_index_list)
47
+ {
48
+ this.allocated_items_by_grouper_index[grouper_index] = new AllocatedItemManager(templates)
49
+ }
50
+ }
51
+
52
+ /**
53
+ * @param merged_containers - Merged container geometry.
54
+ */
55
+ merge_allocated_items(merged_containers: MergedContainers): void
56
+ {
57
+ if (Object.keys(this.allocated_items_by_grouper_index).length > 0)
58
+ {
59
+ return
60
+ }
61
+ this.create_allocated_items_by_grouper(merged_containers.list_grouper_indexes())
62
+ for (const grouper of merged_containers.list_grouper_indexes())
63
+ {
64
+ merge_grouper_items(this, merged_containers, grouper)
65
+ }
66
+ }
67
+
68
+ /**
69
+ * @returns Shared item templates.
70
+ */
71
+ get_item_templates(): ItemTemplates
72
+ {
73
+ const keys = Object.keys(this.allocated_items_by_sequence_index)
74
+ const first_key = Number(keys[0])
75
+ return this.allocated_items_by_sequence_index[first_key].templates
76
+ }
77
+ }
78
+
79
+ /**
80
+ * @param multi - Multi-container item holder.
81
+ * @param merged - Merged containers.
82
+ * @param grouper - Grouper id.
83
+ */
84
+ function merge_grouper_items(
85
+ multi: MultiContainerAllocatedItems,
86
+ merged: MergedContainers,
87
+ grouper: number
88
+ ): void
89
+ {
90
+ const grouped = merged.get_container_by_grouper_index(grouper)
91
+ let last_end = 0
92
+ for (const sequence_index of grouped.list_containers_sequence_indexes())
93
+ {
94
+ const sequence_items = multi.get_allocated_items_by_sequence_index(sequence_index)
95
+ const grouper_items = multi.get_allocated_items_by_grouper_index(grouper)
96
+ for (const item_index of sequence_items.list_item_indexes())
97
+ {
98
+ const source = sequence_items.get_item(item_index)
99
+ const item = clone_allocated_item(source)
100
+ item.zi += last_end
101
+ grouper_items.add_allocated_items([item])
102
+ }
103
+ const container = grouped.get_container_by_sequence_index(sequence_index)
104
+ last_end += container.length
105
+ }
106
+ }
107
+
108
+ /**
109
+ * @param source - Sequence-level allocated item.
110
+ * @returns Copy safe to offset for grouper merge.
111
+ */
112
+ function clone_allocated_item(source: AllocatedItem): AllocatedItem
113
+ {
114
+ const item = new AllocatedItem(source.templates, source.template_index)
115
+ item.xi = source.xi
116
+ item.yi = source.yi
117
+ item.zi = source.zi
118
+ item.rotation = source.rotation
119
+ return item
120
+ }
@@ -0,0 +1,29 @@
1
+ import type { RotationCode } from '../../contracts/rotation_enum.js'
2
+ import { ROTATION } from '../../contracts/rotation_enum.js'
3
+
4
+ const WIDTH = 0
5
+ const LENGTH = 1
6
+ const HEIGHT = 2
7
+
8
+ const ROTATION_DIM_INDEX: Record<RotationCode, [number, number, number]> = {
9
+ [ROTATION.POS1]: [WIDTH, LENGTH, HEIGHT],
10
+ [ROTATION.POS2]: [WIDTH, HEIGHT, LENGTH],
11
+ [ROTATION.POS3]: [HEIGHT, LENGTH, WIDTH],
12
+ [ROTATION.POS4]: [LENGTH, WIDTH, HEIGHT],
13
+ [ROTATION.POS5]: [HEIGHT, WIDTH, LENGTH],
14
+ [ROTATION.POS6]: [LENGTH, HEIGHT, WIDTH]
15
+ }
16
+
17
+ /**
18
+ * @param rotation - Rotation code.
19
+ * @param dimensions - [width, length, height].
20
+ * @returns Rotated [width, length, height].
21
+ */
22
+ export function rotate_dimensions(
23
+ rotation: RotationCode,
24
+ dimensions: [number, number, number]
25
+ ): [number, number, number]
26
+ {
27
+ const index = ROTATION_DIM_INDEX[rotation]
28
+ return [dimensions[index[0]], dimensions[index[1]], dimensions[index[2]]]
29
+ }
@@ -0,0 +1,109 @@
1
+ import { VEHICLE_TYPE } from '../../contracts/vehicle_type.js'
2
+ import type { TransportRecord } from '../../contracts/transport_record.js'
3
+ import { Transport } from '../transports/transport.js'
4
+ import { BitremModel } from './bitrem_model.js'
5
+ import { RodotremModel } from './rodotrem_model.js'
6
+ import { VanderleiaModel } from './vanderleia_model.js'
7
+ import { SimpleTruckModel } from './simple_truck_model.js'
8
+ import { SemiReboqueModel } from './semi_reboque_model.js'
9
+ import { CenterOfMass } from '../items/center_of_mass.js'
10
+ import type { AllocatedItemManager } from '../items/allocated_item_manager.js'
11
+ import { MultiContainerAllocatedItems } from '../items/multi_container_allocated_items.js'
12
+ import { ChassiForces } from './chassi_forces.js'
13
+ import { PercentageOnAxlesCalculator } from './percentage_on_axles_calculator.js'
14
+
15
+ type VehicleModel = {
16
+ calculate_chassi_forces_with_load_center_of_mass: (
17
+ center_of_mass_by_grouper: Record<number, CenterOfMass>
18
+ ) => ChassiForces
19
+ calculate_weight_on_axles: (
20
+ multi_items: import('../items/multi_container_allocated_items.js').MultiContainerAllocatedItems
21
+ ) => number[]
22
+ }
23
+
24
+ /**
25
+ * Dispatches to vehicle-specific axle weight models.
26
+ */
27
+ export class AxleWeightModel
28
+ {
29
+ private readonly model: VehicleModel
30
+ private readonly transport: Transport
31
+
32
+ /**
33
+ * @param transport_or_data - Parsed transport or raw wire dict.
34
+ */
35
+ constructor(transport_or_data: Transport | TransportRecord)
36
+ {
37
+ this.transport = transport_or_data instanceof Transport
38
+ ? transport_or_data
39
+ : new Transport(transport_or_data)
40
+ this.model = select_vehicle_model(this.transport)
41
+ }
42
+
43
+ /**
44
+ * @param center_of_mass_by_grouper - Precomputed CM per grouper.
45
+ * @returns Chassis force result.
46
+ */
47
+ calculate_chassi_forces_with_load_center_of_mass(
48
+ center_of_mass_by_grouper: Record<number, CenterOfMass>
49
+ ): ChassiForces
50
+ {
51
+ return this.model.calculate_chassi_forces_with_load_center_of_mass(
52
+ center_of_mass_by_grouper)
53
+ }
54
+
55
+ /**
56
+ * @param allocated_by_sequence - Items per container sequence index.
57
+ * @returns Loaded cargo per axle.
58
+ */
59
+ calculate_weight_on_axles(
60
+ allocated_by_sequence: Record<number, AllocatedItemManager>
61
+ ): number[]
62
+ {
63
+ const multi = new MultiContainerAllocatedItems(allocated_by_sequence)
64
+ return this.model.calculate_weight_on_axles(multi)
65
+ }
66
+
67
+ /**
68
+ * @param allocated_by_sequence - Items per container sequence index.
69
+ * @returns Utilization percentage per axle.
70
+ */
71
+ calculate_percentages_on_axles(
72
+ allocated_by_sequence: Record<number, AllocatedItemManager>
73
+ ): number[]
74
+ {
75
+ const weights = this.calculate_weight_on_axles(allocated_by_sequence)
76
+ return new PercentageOnAxlesCalculator(this.transport)
77
+ .weight_on_axles_to_percentages(weights)
78
+ }
79
+ }
80
+
81
+ /**
82
+ * @param transport - Parsed transport.
83
+ * @returns Vehicle model implementation.
84
+ */
85
+ function select_vehicle_model(transport: Transport): VehicleModel
86
+ {
87
+ const type = transport.vehicle_type
88
+ if (type === VEHICLE_TYPE.SEMIREBOQUE || type === VEHICLE_TYPE.REBAIXADO)
89
+ {
90
+ return new SemiReboqueModel(transport)
91
+ }
92
+ if (type === VEHICLE_TYPE.BITREM)
93
+ {
94
+ return new BitremModel(transport)
95
+ }
96
+ if (type === VEHICLE_TYPE.RODOTREM)
97
+ {
98
+ return new RodotremModel(transport)
99
+ }
100
+ if (type === VEHICLE_TYPE.VANDERLEIA)
101
+ {
102
+ return new VanderleiaModel(transport)
103
+ }
104
+ if (type === VEHICLE_TYPE.CAMINHAO || type === VEHICLE_TYPE.VUC)
105
+ {
106
+ return new SimpleTruckModel(transport)
107
+ }
108
+ throw new Error(`Unsupported vehicle type: ${type}`)
109
+ }
@@ -0,0 +1,74 @@
1
+ import type { Transport } from '../transports/transport.js'
2
+ import { Chassi } from '../transports/chassi.js'
3
+ import { CHASSI_REFERENCE } from '../../contracts/chassi_reference.js'
4
+ import { CenterOfMass } from '../items/center_of_mass.js'
5
+ import { ChassiForces } from './chassi_forces.js'
6
+ import { SimpleTruckBase } from './simple_truck_base.js'
7
+ import { solve_linear_system } from '../../math/gaussian_elimination.js'
8
+
9
+ /**
10
+ * Bitruck caminhão: equivalent 2-axle truck + front axle pair split.
11
+ */
12
+ export class BiTruckModel
13
+ {
14
+ private readonly chassi: Chassi
15
+ readonly equivalent_truck: SimpleTruckBase
16
+
17
+ /**
18
+ * @param transport - Parsed transport.
19
+ */
20
+ constructor(transport: Transport)
21
+ {
22
+ this.chassi = new Chassi(transport)
23
+ this.equivalent_truck = new SimpleTruckBase(transport)
24
+ this.equivalent_truck.set_axles_positions(get_equivalent_positions(this.chassi, transport))
25
+ }
26
+
27
+ /**
28
+ * @param center_of_mass_by_grouper - CM per grouper.
29
+ * @returns Three-axle forces.
30
+ */
31
+ calculate_chassi_forces_with_load_center_of_mass(
32
+ center_of_mass_by_grouper: Record<number, CenterOfMass>
33
+ ): ChassiForces
34
+ {
35
+ const equivalent = this.equivalent_truck
36
+ .calculate_chassi_forces_with_load_center_of_mass(center_of_mass_by_grouper)
37
+ const equivalent_z = this.equivalent_truck.axles_positions[0]
38
+ const independent = [
39
+ equivalent.get_force_on_axle(0),
40
+ equivalent.get_force_on_axle(0) * equivalent_z
41
+ ]
42
+ const front = solve_linear_system(generate_front_matrix(this.chassi), independent)
43
+ const forces = new ChassiForces()
44
+ forces.add_axle_forces([front[0], front[1], equivalent.get_force_on_axle(1)])
45
+ return forces
46
+ }
47
+ }
48
+
49
+ /**
50
+ * @param chassi - Chassis geometry.
51
+ * @returns 2×2 front axle matrix.
52
+ */
53
+ function generate_front_matrix(chassi: Chassi): number[][]
54
+ {
55
+ const axle_1 = chassi.get_axle_position(0, CHASSI_REFERENCE.GROUPER_1)
56
+ const axle_2 = chassi.get_axle_position(1, CHASSI_REFERENCE.GROUPER_1)
57
+ return [[1, 1], [axle_1, axle_2]]
58
+ }
59
+
60
+ /**
61
+ * @param chassi - Chassis geometry.
62
+ * @param transport - Parsed transport.
63
+ * @returns Equivalent two-axle positions.
64
+ */
65
+ function get_equivalent_positions(chassi: Chassi, transport: Transport): number[]
66
+ {
67
+ const axle_1 = chassi.get_axle_position(0, CHASSI_REFERENCE.GROUPER_1)
68
+ const axle_2 = chassi.get_axle_position(1, CHASSI_REFERENCE.GROUPER_1)
69
+ const axle_3 = chassi.get_axle_position(2, CHASSI_REFERENCE.GROUPER_1)
70
+ const cap_1 = transport.axle_manager.get_axle(0).max_supported_weight
71
+ const cap_2 = transport.axle_manager.get_axle(1).max_supported_weight
72
+ const front_equivalent = (axle_1 * cap_1 + axle_2 * cap_2) / (cap_1 + cap_2)
73
+ return [front_equivalent, axle_3]
74
+ }
@@ -0,0 +1,86 @@
1
+ import type { Transport } from '../transports/transport.js'
2
+ import { Chassi } from '../transports/chassi.js'
3
+ import { CHASSI_REFERENCE } from '../../contracts/chassi_reference.js'
4
+ import { CenterOfMass } from '../items/center_of_mass.js'
5
+ import { ChassiForces } from './chassi_forces.js'
6
+ import { SemiReboqueBase } from './semi_reboque_base.js'
7
+ import { solve_linear_system } from '../../math/gaussian_elimination.js'
8
+
9
+ /**
10
+ * Bitruck tractor + semi-trailer variant.
11
+ */
12
+ export class BiTruckTractorSemiTrailerModel
13
+ {
14
+ private readonly chassi: Chassi
15
+ readonly equivalent_semi_trailer: SemiReboqueBase
16
+
17
+ /**
18
+ * @param transport - Parsed transport.
19
+ */
20
+ constructor(transport: Transport)
21
+ {
22
+ this.chassi = new Chassi(transport)
23
+ this.equivalent_semi_trailer = new SemiReboqueBase(transport)
24
+ this.equivalent_semi_trailer.set_linear_system_matrix(
25
+ get_equivalent_positions(this.chassi, transport))
26
+ }
27
+
28
+ /**
29
+ * @param center_of_mass_by_grouper - CM per grouper.
30
+ * @returns Four-axle + pin forces.
31
+ */
32
+ calculate_chassi_forces_with_load_center_of_mass(
33
+ center_of_mass_by_grouper: Record<number, CenterOfMass>
34
+ ): ChassiForces
35
+ {
36
+ const equivalent = this.equivalent_semi_trailer
37
+ .calculate_chassi_forces_with_load_center_of_mass(center_of_mass_by_grouper)
38
+ const equivalent_z = this.equivalent_semi_trailer.chassi_positions[1]
39
+ const independent = [
40
+ equivalent.get_force_on_axle(0),
41
+ equivalent.get_force_on_axle(0) * equivalent_z
42
+ ]
43
+ const front = solve_linear_system(generate_tractor_front_matrix(this.chassi), independent)
44
+ const forces = new ChassiForces()
45
+ forces.add_axle_forces([
46
+ front[0],
47
+ front[1],
48
+ equivalent.get_force_on_axle(1),
49
+ equivalent.get_force_on_axle(2)
50
+ ])
51
+ forces.add_pin_forces([equivalent.get_force_on_pin(0)])
52
+ return forces
53
+ }
54
+ }
55
+
56
+ /**
57
+ * @param chassi - Chassis geometry.
58
+ * @returns 2×2 tractor front matrix.
59
+ */
60
+ function generate_tractor_front_matrix(chassi: Chassi): number[][]
61
+ {
62
+ const axle_1 = chassi.get_axle_position(0, CHASSI_REFERENCE.TRACTOR)
63
+ const axle_2 = chassi.get_axle_position(1, CHASSI_REFERENCE.TRACTOR)
64
+ return [[1, 1], [axle_1, axle_2]]
65
+ }
66
+
67
+ /**
68
+ * @param chassi - Chassis geometry.
69
+ * @param transport - Parsed transport.
70
+ * @returns Equivalent semi chassis positions.
71
+ */
72
+ function get_equivalent_positions(chassi: Chassi, transport: Transport): number[]
73
+ {
74
+ const tractor_pin = chassi.get_pin_position(0, CHASSI_REFERENCE.TRACTOR)
75
+ const tractor_axle_1 = chassi.get_axle_position(0, CHASSI_REFERENCE.TRACTOR)
76
+ const tractor_axle_2 = chassi.get_axle_position(1, CHASSI_REFERENCE.TRACTOR)
77
+ const tractor_axle_3 = chassi.get_axle_position(2, CHASSI_REFERENCE.TRACTOR)
78
+ const semi_pin = chassi.get_pin_position(0, CHASSI_REFERENCE.GROUPER_1)
79
+ const semi_axle_4 = chassi.get_axle_position(3, CHASSI_REFERENCE.GROUPER_1)
80
+ const cap_1 = transport.axle_manager.get_axle(0).max_supported_weight
81
+ const cap_2 = transport.axle_manager.get_axle(1).max_supported_weight
82
+ const tractor_equivalent = (
83
+ tractor_axle_1 * cap_1 + tractor_axle_2 * cap_2
84
+ ) / (cap_1 + cap_2)
85
+ return [tractor_pin, tractor_equivalent, tractor_axle_3, semi_pin, semi_axle_4]
86
+ }
@@ -0,0 +1,148 @@
1
+ import type { Transport } from '../transports/transport.js'
2
+ import type { MultiContainerAllocatedItems } from '../items/multi_container_allocated_items.js'
3
+ import { calculate_chassi_forces_from_multi } from '../items/compute_grouper_center_of_mass.js'
4
+ import { Chassi } from '../transports/chassi.js'
5
+ import { CHASSI_REFERENCE } from '../../contracts/chassi_reference.js'
6
+ import { CenterOfMass } from '../items/center_of_mass.js'
7
+ import { ChassiForces } from './chassi_forces.js'
8
+ import { solve_linear_system } from '../../math/gaussian_elimination.js'
9
+
10
+ /**
11
+ * Bitrem interlink + semi static equilibrium (6×6 system).
12
+ */
13
+ export class BitremModel
14
+ {
15
+ readonly chassi: Chassi
16
+ private readonly matrix: number[][]
17
+
18
+ /**
19
+ * @param transport - Parsed transport.
20
+ */
21
+ constructor(private readonly transport: Transport)
22
+ {
23
+ this.chassi = new Chassi(transport)
24
+ this.matrix = generate_bitrem_matrix(this.chassi)
25
+ }
26
+
27
+ /**
28
+ * @param multi_items - Allocated items by container sequence.
29
+ * @returns Loaded weight per axle.
30
+ */
31
+ calculate_weight_on_axles(multi_items: MultiContainerAllocatedItems): number[]
32
+ {
33
+ const forces = this.calculate_chassi_forces(multi_items)
34
+ return forces.list_axles_indexes().map((index) => forces.get_force_on_axle(index))
35
+ }
36
+
37
+ /**
38
+ * @param multi_items - Allocated items.
39
+ * @returns Chassis forces before rebalance split on axles 3–4.
40
+ */
41
+ calculate_chassi_forces(multi_items: MultiContainerAllocatedItems): ChassiForces
42
+ {
43
+ return calculate_chassi_forces_from_multi(
44
+ this.transport,
45
+ multi_items,
46
+ (center_of_mass_by_grouper) =>
47
+ this.calculate_chassi_forces_with_load_center_of_mass(center_of_mass_by_grouper))
48
+ }
49
+
50
+ /**
51
+ * @param center_of_mass_by_grouper - CM for groupers 1 and 2.
52
+ * @returns Combined chassis forces.
53
+ */
54
+ calculate_chassi_forces_with_load_center_of_mass(
55
+ center_of_mass_by_grouper: Record<number, CenterOfMass>
56
+ ): ChassiForces
57
+ {
58
+ const interlink = center_of_mass_by_grouper[1]
59
+ const semi = center_of_mass_by_grouper[2]
60
+ const solution_interlink = solve_interlink_system(this.matrix, interlink)
61
+ const solution_semi = solve_semi_system(this.matrix, semi)
62
+ const forces = new ChassiForces()
63
+ forces.add_pin_forces([
64
+ solution_interlink[3] + solution_semi[3],
65
+ solution_interlink[1] + solution_semi[1]
66
+ ])
67
+ const loaded = [
68
+ solution_interlink[5] + solution_semi[5],
69
+ solution_interlink[4] + solution_semi[4],
70
+ solution_interlink[2],
71
+ solution_semi[2],
72
+ solution_interlink[0] + solution_semi[0]
73
+ ]
74
+ forces.add_axle_forces(linked_axle_weight_rebalance(this.transport, loaded))
75
+ return forces
76
+ }
77
+ }
78
+
79
+ /**
80
+ * @param chassi - Chassis geometry.
81
+ * @returns 6×6 matrix coefficients.
82
+ */
83
+ function generate_bitrem_matrix(chassi: Chassi): number[][]
84
+ {
85
+ const tractor_pin = chassi.get_pin_position(0, CHASSI_REFERENCE.TRACTOR)
86
+ const tractor_axle_1 = chassi.get_axle_position(0, CHASSI_REFERENCE.TRACTOR)
87
+ const tractor_axle_2 = chassi.get_axle_position(1, CHASSI_REFERENCE.TRACTOR)
88
+ const interlink_pin_1 = chassi.get_pin_position(0, CHASSI_REFERENCE.GROUPER_1)
89
+ const interlink_pin_2 = chassi.get_pin_position(1, CHASSI_REFERENCE.GROUPER_1)
90
+ const interlink_axle_3 = chassi.get_axle_position(2, CHASSI_REFERENCE.GROUPER_1)
91
+ const semi_pin_2 = chassi.get_pin_position(1, CHASSI_REFERENCE.GROUPER_2)
92
+ const semi_axle_4 = chassi.get_axle_position(4, CHASSI_REFERENCE.GROUPER_2)
93
+ return [
94
+ [1, 1, 0, 0, 0, 0],
95
+ [semi_axle_4, semi_pin_2, 0, 0, 0, 0],
96
+ [0, -1, 1, 1, 0, 0],
97
+ [0, -interlink_pin_2, interlink_axle_3, interlink_pin_1, 0, 0],
98
+ [0, 0, 0, -1, 1, 1],
99
+ [0, 0, 0, -tractor_pin, tractor_axle_2, tractor_axle_1]
100
+ ]
101
+ }
102
+
103
+ /**
104
+ * @param matrix - System matrix.
105
+ * @param center_of_mass - Interlink load CM.
106
+ * @returns Solution vector.
107
+ */
108
+ function solve_interlink_system(matrix: number[][], center_of_mass: CenterOfMass): number[]
109
+ {
110
+ const independent = [0, 0, center_of_mass.mass, center_of_mass.mass * center_of_mass.z, 0, 0]
111
+ return solve_linear_system(matrix, independent)
112
+ }
113
+
114
+ /**
115
+ * @param matrix - System matrix.
116
+ * @param center_of_mass - Semi load CM.
117
+ * @returns Solution vector.
118
+ */
119
+ function solve_semi_system(matrix: number[][], center_of_mass: CenterOfMass): number[]
120
+ {
121
+ const independent = [
122
+ center_of_mass.mass,
123
+ center_of_mass.mass * center_of_mass.z,
124
+ 0,
125
+ 0,
126
+ 0,
127
+ 0
128
+ ]
129
+ return solve_linear_system(matrix, independent)
130
+ }
131
+
132
+ /**
133
+ * @param transport - Parsed transport.
134
+ * @param loaded_weights - Raw axle loads before rebalance.
135
+ * @returns Rebalanced axle 3–4 loads.
136
+ */
137
+ function linked_axle_weight_rebalance(transport: Transport, loaded_weights: number[]): number[]
138
+ {
139
+ const first = transport.axle_manager.get_axle(2)
140
+ const second = transport.axle_manager.get_axle(3)
141
+ const first_cap = first.max_supported_weight - first.tare
142
+ const second_cap = second.max_supported_weight - second.tare
143
+ const total_cap = first_cap + second_cap
144
+ const total_load = loaded_weights[2] + loaded_weights[3]
145
+ loaded_weights[2] = (first_cap / total_cap) * total_load
146
+ loaded_weights[3] = (second_cap / total_cap) * total_load
147
+ return loaded_weights
148
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Pin and axle reaction forces from static equilibrium solution.
3
+ */
4
+ export class ChassiForces
5
+ {
6
+ private pin_forces: number[] = []
7
+ private axle_forces: number[] = []
8
+
9
+ /**
10
+ * @param pin_forces_list - Pin reaction forces.
11
+ */
12
+ add_pin_forces(pin_forces_list: number[]): void
13
+ {
14
+ this.pin_forces = pin_forces_list.map((value) => Number(value))
15
+ }
16
+
17
+ /**
18
+ * @param axle_forces_list - Axle reaction forces (cargo load per axle).
19
+ */
20
+ add_axle_forces(axle_forces_list: number[]): void
21
+ {
22
+ this.axle_forces = axle_forces_list.map((value) => Number(value))
23
+ }
24
+
25
+ /**
26
+ * @param axle_index - Zero-based axle index.
27
+ * @returns Force on axle.
28
+ */
29
+ get_force_on_axle(axle_index: number): number
30
+ {
31
+ return this.axle_forces[axle_index]
32
+ }
33
+
34
+ /**
35
+ * @param pin_index - Zero-based pin index.
36
+ * @returns Force on pin.
37
+ */
38
+ get_force_on_pin(pin_index: number): number
39
+ {
40
+ return this.pin_forces[pin_index]
41
+ }
42
+
43
+ /**
44
+ * @returns Axle index list.
45
+ */
46
+ list_axles_indexes(): number[]
47
+ {
48
+ return this.axle_forces.map((_force, index) => index)
49
+ }
50
+ }