fleet_routing.proto 123 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706
  1. // Copyright 2022 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. syntax = "proto3";
  15. package google.cloud.optimization.v1;
  16. import "google/api/annotations.proto";
  17. import "google/api/client.proto";
  18. import "google/api/field_behavior.proto";
  19. import "google/cloud/optimization/v1/async_model.proto";
  20. import "google/longrunning/operations.proto";
  21. import "google/protobuf/duration.proto";
  22. import "google/protobuf/timestamp.proto";
  23. import "google/type/latlng.proto";
  24. option go_package = "google.golang.org/genproto/googleapis/cloud/optimization/v1;optimization";
  25. option java_multiple_files = true;
  26. option java_outer_classname = "FleetRoutingProto";
  27. option java_package = "com.google.cloud.optimization.v1";
  28. // A service for optimizing vehicle tours.
  29. //
  30. // Validity of certain types of fields:
  31. //
  32. // * `google.protobuf.Timestamp`
  33. // * Times are in Unix time: seconds since 1970-01-01T00:00:00+00:00.
  34. // * seconds must be in [0, 253402300799],
  35. // i.e. in [1970-01-01T00:00:00+00:00, 9999-12-31T23:59:59+00:00].
  36. // * nanos must be unset or set to 0.
  37. // * `google.protobuf.Duration`
  38. // * seconds must be in [0, 253402300799],
  39. // i.e. in [1970-01-01T00:00:00+00:00, 9999-12-31T23:59:59+00:00].
  40. // * nanos must be unset or set to 0.
  41. // * `google.type.LatLng`
  42. // * latitude must be in [-90.0, 90.0].
  43. // * longitude must be in [-180.0, 180.0].
  44. // * at least one of latitude and longitude must be non-zero.
  45. service FleetRouting {
  46. option (google.api.default_host) = "cloudoptimization.googleapis.com";
  47. option (google.api.oauth_scopes) =
  48. "https://www.googleapis.com/auth/cloud-platform";
  49. // Sends an `OptimizeToursRequest` containing a `ShipmentModel` and returns an
  50. // `OptimizeToursResponse` containing `ShipmentRoute`s, which are a set of
  51. // routes to be performed by vehicles minimizing the overall cost.
  52. //
  53. // A `ShipmentModel` model consists mainly of `Shipment`s that need to be
  54. // carried out and `Vehicle`s that can be used to transport the `Shipment`s.
  55. // The `ShipmentRoute`s assign `Shipment`s to `Vehicle`s. More specifically,
  56. // they assign a series of `Visit`s to each vehicle, where a `Visit`
  57. // corresponds to a `VisitRequest`, which is a pickup or delivery for a
  58. // `Shipment`.
  59. //
  60. // The goal is to provide an assignment of `ShipmentRoute`s to `Vehicle`s that
  61. // minimizes the total cost where cost has many components defined in the
  62. // `ShipmentModel`.
  63. rpc OptimizeTours(OptimizeToursRequest) returns (OptimizeToursResponse) {
  64. option (google.api.http) = {
  65. post: "/v1/{parent=projects/*/locations/*}:optimizeTours"
  66. body: "*"
  67. additional_bindings {
  68. post: "/v1/{parent=projects/*}:optimizeTours"
  69. body: "*"
  70. }
  71. };
  72. }
  73. // Optimizes vehicle tours for one or more `OptimizeToursRequest`
  74. // messages as a batch.
  75. //
  76. // This method is a Long Running Operation (LRO). The inputs for optimization
  77. // (`OptimizeToursRequest` messages) and outputs (`OptimizeToursResponse`
  78. // messages) are read/written from/to Cloud Storage in user-specified
  79. // format. Like the `OptimizeTours` method, each `OptimizeToursRequest`
  80. // contains a `ShipmentModel` and returns an `OptimizeToursResponse`
  81. // containing `ShipmentRoute`s, which are a set of routes to be performed by
  82. // vehicles minimizing the overall cost.
  83. rpc BatchOptimizeTours(BatchOptimizeToursRequest)
  84. returns (google.longrunning.Operation) {
  85. option (google.api.http) = {
  86. post: "/v1/{parent=projects/*/locations/*}:batchOptimizeTours"
  87. body: "*"
  88. additional_bindings {
  89. post: "/v1/{parent=projects/*}:batchOptimizeTours"
  90. body: "*"
  91. }
  92. };
  93. option (google.longrunning.operation_info) = {
  94. response_type: "BatchOptimizeToursResponse"
  95. metadata_type: "AsyncModelMetadata"
  96. };
  97. }
  98. }
  99. // Request to be given to a tour optimization solver which defines the
  100. // shipment model to solve as well as optimization parameters.
  101. message OptimizeToursRequest {
  102. // Defines how the solver should handle the request. In all modes but
  103. // `VALIDATE_ONLY`, if the request is invalid, you will receive an
  104. // `INVALID_REQUEST` error. See
  105. // [max_validation_errors][google.cloud.optimization.v1.OptimizeToursRequest.max_validation_errors]
  106. // to cap the number of errors returned.
  107. enum SolvingMode {
  108. // Solve the model.
  109. DEFAULT_SOLVE = 0;
  110. // Only validates the model without solving it: populates as many
  111. // [OptimizeToursResponse.validation_errors][google.cloud.optimization.v1.OptimizeToursResponse.validation_errors]
  112. // as possible.
  113. VALIDATE_ONLY = 1;
  114. // Only populates
  115. // [OptimizeToursResponse.skipped_shipments][google.cloud.optimization.v1.OptimizeToursResponse.skipped_shipments],
  116. // and doesn't actually solve the rest of the request (`status` and `routes`
  117. // are unset in the response).
  118. //
  119. // *IMPORTANT*: not all infeasible shipments are returned here, but only the
  120. // ones that are detected as infeasible as a preprocessing.
  121. DETECT_SOME_INFEASIBLE_SHIPMENTS = 2;
  122. }
  123. // Mode defining the behavior of the search, trading off latency versus
  124. // solution quality. In all modes, the global request deadline is enforced.
  125. enum SearchMode {
  126. // Unspecified search mode, equivalent to `RETURN_FAST`.
  127. SEARCH_MODE_UNSPECIFIED = 0;
  128. // Stop the search after finding the first good solution.
  129. RETURN_FAST = 1;
  130. // Spend all the available time to search for better solutions.
  131. CONSUME_ALL_AVAILABLE_TIME = 2;
  132. }
  133. // Required. Target project and location to make a call.
  134. //
  135. // Format: `projects/{project-id}/locations/{location-id}`.
  136. //
  137. // If no location is specified, a region will be chosen automatically.
  138. string parent = 1 [(google.api.field_behavior) = REQUIRED];
  139. // If this timeout is set, the server returns a response before the timeout
  140. // period has elapsed or the server deadline for synchronous requests is
  141. // reached, whichever is sooner.
  142. //
  143. // For asynchronous requests, the server will generate a solution (if
  144. // possible) before the timeout has elapsed.
  145. google.protobuf.Duration timeout = 2;
  146. // Shipment model to solve.
  147. ShipmentModel model = 3;
  148. // By default, the solving mode is `DEFAULT_SOLVE` (0).
  149. SolvingMode solving_mode = 4;
  150. // Truncates the number of validation errors returned. Those errors are
  151. // typically attached to an INVALID_ARGUMENT error payload as a BadRequest
  152. // error detail (https://cloud.google.com/apis/design/errors#error_details),
  153. // unless solving_mode=VALIDATE_ONLY: see the
  154. // [OptimizeToursResponse.validation_errors][google.cloud.optimization.v1.OptimizeToursResponse.validation_errors]
  155. // field.
  156. // This defaults to 100 and is capped at 10,000.
  157. optional int32 max_validation_errors = 5;
  158. // Search mode used to solve the request.
  159. SearchMode search_mode = 6;
  160. // Guide the optimization algorithm in finding a first solution that is
  161. // similar to a previous solution.
  162. //
  163. // The model is constrained when the first solution is built.
  164. // Any shipments not performed on a route are implicitly skipped in the first
  165. // solution, but they may be performed in successive solutions.
  166. //
  167. // The solution must satisfy some basic validity assumptions:
  168. //
  169. // * for all routes, `vehicle_index` must be in range and not be duplicated.
  170. // * for all visits, `shipment_index` and `visit_request_index` must be
  171. // in range.
  172. // * a shipment may only be referenced on one route.
  173. // * the pickup of a pickup-delivery shipment must be performed before
  174. // the delivery.
  175. // * no more than one pickup alternative or delivery alternative of
  176. // a shipment may be performed.
  177. // * for all routes, times are increasing (i.e., `vehicle_start_time
  178. // <= visits[0].start_time <= visits[1].start_time ...
  179. // <= vehicle_end_time`).
  180. // * a shipment may only be performed on a vehicle that is allowed. A
  181. // vehicle is allowed if
  182. // [Shipment.allowed_vehicle_indices][google.cloud.optimization.v1.Shipment.allowed_vehicle_indices]
  183. // is empty or its `vehicle_index` is included in
  184. // [Shipment.allowed_vehicle_indices][google.cloud.optimization.v1.Shipment.allowed_vehicle_indices].
  185. //
  186. // If the injected solution is not feasible, a validation error is not
  187. // necessarily returned and an error indicating infeasibility may be returned
  188. // instead.
  189. repeated ShipmentRoute injected_first_solution_routes = 7;
  190. // Constrain the optimization algorithm to find a final solution that is
  191. // similar to a previous solution. For example, this may be used to freeze
  192. // portions of routes which have already been completed or which are to be
  193. // completed but must not be modified.
  194. //
  195. // If the injected solution is not feasible, a validation error is not
  196. // necessarily returned and an error indicating infeasibility may be returned
  197. // instead.
  198. InjectedSolutionConstraint injected_solution_constraint = 8;
  199. // If non-empty, the given routes will be refreshed, without modifying their
  200. // underlying sequence of visits or travel times: only other details will be
  201. // updated. This does not solve the model.
  202. //
  203. // As of 2020/11, this only populates the polylines of non-empty routes and
  204. // requires that `populate_polylines` is true.
  205. //
  206. // The `route_polyline` fields of the passed-in routes may be inconsistent
  207. // with route `transitions`.
  208. //
  209. // This field must not be used together with `injected_first_solution_routes`
  210. // or `injected_solution_constraint`.
  211. //
  212. // `Shipment.ignore` and `Vehicle.ignore` have no effect on the behavior.
  213. // Polylines are still populated between all visits in all non-empty routes
  214. // regardless of whether the related shipments or vehicles are ignored.
  215. repeated ShipmentRoute refresh_details_routes = 9;
  216. // If true:
  217. //
  218. // * uses
  219. // [ShipmentRoute.vehicle_label][google.cloud.optimization.v1.ShipmentRoute.vehicle_label]
  220. // instead of `vehicle_index` to
  221. // match routes in an injected solution with vehicles in the request;
  222. // reuses the mapping of original
  223. // [ShipmentRoute.vehicle_index][google.cloud.optimization.v1.ShipmentRoute.vehicle_index]
  224. // to new
  225. // [ShipmentRoute.vehicle_index][google.cloud.optimization.v1.ShipmentRoute.vehicle_index]
  226. // to update
  227. // [ConstraintRelaxation.vehicle_indices][google.cloud.optimization.v1.InjectedSolutionConstraint.ConstraintRelaxation.vehicle_indices]
  228. // if non-empty, but the mapping must be unambiguous (i.e., multiple
  229. // `ShipmentRoute`s must not share the same original `vehicle_index`).
  230. // * uses
  231. // [ShipmentRoute.Visit.shipment_label][google.cloud.optimization.v1.ShipmentRoute.Visit.shipment_label]
  232. // instead of `shipment_index`
  233. // to match visits in an injected solution with shipments in the request;
  234. // * uses
  235. // [SkippedShipment.label][google.cloud.optimization.v1.SkippedShipment.label]
  236. // instead of
  237. // [SkippedShipment.index][google.cloud.optimization.v1.SkippedShipment.index]
  238. // to
  239. // match skipped shipments in the injected solution with request
  240. // shipments.
  241. //
  242. // This interpretation applies to the `injected_first_solution_routes`,
  243. // `injected_solution_constraint`, and `refresh_details_routes` fields.
  244. // It can be used when shipment or vehicle indices in the request have
  245. // changed since the solution was created, perhaps because shipments or
  246. // vehicles have been removed from or added to the request.
  247. //
  248. // If true, labels in the following categories must appear at most once in
  249. // their category:
  250. //
  251. // * [Vehicle.label][google.cloud.optimization.v1.Vehicle.label] in the
  252. // request;
  253. // * [Shipment.label][google.cloud.optimization.v1.Shipment.label] in the
  254. // request;
  255. // * [ShipmentRoute.vehicle_label][google.cloud.optimization.v1.ShipmentRoute.vehicle_label] in the injected solution;
  256. // * [SkippedShipment.label][google.cloud.optimization.v1.SkippedShipment.label] and [ShipmentRoute.Visit.shipment_label][google.cloud.optimization.v1.ShipmentRoute.Visit.shipment_label] in
  257. // the injected solution (except pickup/delivery visit pairs, whose
  258. // `shipment_label` must appear twice).
  259. //
  260. // If a `vehicle_label` in the injected solution does not correspond to a
  261. // request vehicle, the corresponding route is removed from the solution
  262. // along with its visits. If a `shipment_label` in the injected solution does
  263. // not correspond to a request shipment, the corresponding visit is removed
  264. // from the solution. If a
  265. // [SkippedShipment.label][google.cloud.optimization.v1.SkippedShipment.label]
  266. // in the injected solution does not correspond to a request shipment, the
  267. // `SkippedShipment` is removed from the solution.
  268. //
  269. // Removing route visits or entire routes from an injected solution may
  270. // have an effect on the implied constraints, which may lead to change in
  271. // solution, validation errors, or infeasibility.
  272. //
  273. // NOTE: The caller must ensure that each
  274. // [Vehicle.label][google.cloud.optimization.v1.Vehicle.label] (resp.
  275. // [Shipment.label][google.cloud.optimization.v1.Shipment.label]) uniquely
  276. // identifies a vehicle (resp. shipment) entity used across the two relevant
  277. // requests: the past request that produced the `OptimizeToursResponse` used
  278. // in the injected solution and the current request that includes the injected
  279. // solution. The uniqueness checks described above are not enough to guarantee
  280. // this requirement.
  281. bool interpret_injected_solutions_using_labels = 10;
  282. // Consider traffic estimation in calculating `ShipmentRoute` fields
  283. // [Transition.travel_duration][google.cloud.optimization.v1.ShipmentRoute.Transition.travel_duration],
  284. // [Visit.start_time][google.cloud.optimization.v1.ShipmentRoute.Visit.start_time],
  285. // and `vehicle_end_time`; in setting the
  286. // [ShipmentRoute.has_traffic_infeasibilities][google.cloud.optimization.v1.ShipmentRoute.has_traffic_infeasibilities]
  287. // field, and in calculating the
  288. // [OptimizeToursResponse.total_cost][google.cloud.optimization.v1.OptimizeToursResponse.total_cost]
  289. // field.
  290. bool consider_road_traffic = 11;
  291. // If true, polylines will be populated in response `ShipmentRoute`s.
  292. bool populate_polylines = 12;
  293. // If true, polylines will be populated in response
  294. // [ShipmentRoute.transitions][google.cloud.optimization.v1.ShipmentRoute.transitions].
  295. // Note that in this case, the polylines will also be populated in the
  296. // deprecated `travel_steps`.
  297. bool populate_transition_polylines = 13;
  298. // If this is set, then the request can have a deadline
  299. // (see https://grpc.io/blog/deadlines) of up to 60 minutes.
  300. // Otherwise, the maximum deadline is only 30 minutes.
  301. // Note that long-lived requests have a significantly larger (but still small)
  302. // risk of interruption.
  303. bool allow_large_deadline_despite_interruption_risk = 14;
  304. // If true, travel distances will be computed using geodesic distances instead
  305. // of Google Maps distances, and travel times will be computed using geodesic
  306. // distances with a speed defined by `geodesic_meters_per_second`.
  307. bool use_geodesic_distances = 15;
  308. // When `use_geodesic_distances` is true, this field must be set and defines
  309. // the speed applied to compute travel times. Its value must be at least 1.0
  310. // meters/seconds.
  311. optional double geodesic_meters_per_second = 16;
  312. // Label that may be used to identify this request, reported back in the
  313. // [OptimizeToursResponse.request_label][google.cloud.optimization.v1.OptimizeToursResponse.request_label].
  314. string label = 17;
  315. // Deprecated: Use [OptimizeToursRequest.populate_transition_polylines][]
  316. // instead. If true, polylines will be populated in response
  317. // [ShipmentRoute.transitions][google.cloud.optimization.v1.ShipmentRoute.transitions].
  318. // Note that in this case, the polylines will also be populated in the
  319. // deprecated `travel_steps`.
  320. bool populate_travel_step_polylines = 20 [deprecated = true];
  321. }
  322. // Response after solving a tour optimization problem containing the routes
  323. // followed by each vehicle, the shipments which have been skipped and the
  324. // overall cost of the solution.
  325. message OptimizeToursResponse {
  326. // Overall metrics, aggregated over all routes.
  327. message Metrics {
  328. // Aggregated over the routes. Each metric is the sum (or max, for loads)
  329. // over all
  330. // [ShipmentRoute.metrics][google.cloud.optimization.v1.ShipmentRoute.metrics]
  331. // fields of the same name.
  332. AggregatedMetrics aggregated_route_metrics = 1;
  333. // Number of mandatory shipments skipped.
  334. int32 skipped_mandatory_shipment_count = 2;
  335. // Number of vehicles used. Note: if a vehicle route is empty and
  336. // [Vehicle.used_if_route_is_empty][google.cloud.optimization.v1.Vehicle.used_if_route_is_empty]
  337. // is true, the vehicle is considered used.
  338. int32 used_vehicle_count = 3;
  339. // The earliest start time for a used vehicle, computed as the minimum over
  340. // all used vehicles of
  341. // [ShipmentRoute.vehicle_start_time][google.cloud.optimization.v1.ShipmentRoute.vehicle_start_time].
  342. google.protobuf.Timestamp earliest_vehicle_start_time = 4;
  343. // The latest end time for a used vehicle, computed as the maximum over all
  344. // used vehicles of
  345. // [ShipmentRoute.vehicle_end_time][google.cloud.optimization.v1.ShipmentRoute.vehicle_end_time].
  346. google.protobuf.Timestamp latest_vehicle_end_time = 5;
  347. // Cost of the solution, broken down by cost-related request fields.
  348. // The keys are proto paths, relative to the input OptimizeToursRequest,
  349. // e.g. "model.shipments.pickups.cost", and the values are the total cost
  350. // generated by the corresponding cost field, aggregated over the whole
  351. // solution. In other words, costs["model.shipments.pickups.cost"] is the
  352. // sum of all pickup costs over the solution. All costs defined in the model
  353. // are reported in detail here with the exception of costs related to
  354. // TransitionAttributes that are only reported in an aggregated way as of
  355. // 2022/01.
  356. map<string, double> costs = 10;
  357. // Total cost of the solution. The sum of all values in the costs map.
  358. double total_cost = 6;
  359. }
  360. // Routes computed for each vehicle; the i-th route corresponds to the i-th
  361. // vehicle in the model.
  362. repeated ShipmentRoute routes = 1;
  363. // Copy of the
  364. // [OptimizeToursRequest.label][google.cloud.optimization.v1.OptimizeToursRequest.label],
  365. // if a label was specified in the request.
  366. string request_label = 3;
  367. // The list of all shipments skipped.
  368. repeated SkippedShipment skipped_shipments = 4;
  369. // List of all the validation errors that we were able to detect
  370. // independently. See the "MULTIPLE ERRORS" explanation for the
  371. // [OptimizeToursValidationError][google.cloud.optimization.v1.OptimizeToursValidationError]
  372. // message.
  373. repeated OptimizeToursValidationError validation_errors = 5;
  374. // Duration, distance and usage metrics for this solution.
  375. Metrics metrics = 6;
  376. // Deprecated: Use [Metrics.total_cost][] instead.
  377. // Total cost of the solution. This takes into account all costs: costs per
  378. // per hour and travel hour, fixed vehicle costs, unperformed shipment penalty
  379. // costs, global duration cost, etc.
  380. double total_cost = 2 [deprecated = true];
  381. }
  382. // Request to batch optimize tours as an asynchronous operation.
  383. // Each input file should contain one `OptimizeToursRequest`, and each output
  384. // file will contain one `OptimizeToursResponse`. The request contains
  385. // information to read/write and parse the files. All the input and output files
  386. // should be under the same project.
  387. message BatchOptimizeToursRequest {
  388. // Information for solving one optimization model asynchronously.
  389. message AsyncModelConfig {
  390. // User defined model name, can be used as alias by users to keep track of
  391. // models.
  392. string display_name = 1;
  393. // Required. Information about the input model.
  394. InputConfig input_config = 2 [(google.api.field_behavior) = REQUIRED];
  395. // Required. The desired output location information.
  396. OutputConfig output_config = 3 [(google.api.field_behavior) = REQUIRED];
  397. // If this is set, the model will be solved in the checkpoint mode. In this
  398. // mode, the input model can have a deadline longer than 30 mins without the
  399. // risk of interruption. The model will be solved in multiple short-running
  400. // stages. Each stage generates an intermediate checkpoint
  401. // and stores it in the user's Cloud Storage buckets. The checkpoint
  402. // mode should be preferred over
  403. // allow_large_deadline_despite_interruption_risk since it prevents the risk
  404. // of interruption.
  405. bool enable_checkpoints = 4;
  406. }
  407. // Required. Target project and location to make a call.
  408. //
  409. // Format: `projects/{project-id}/locations/{location-id}`.
  410. //
  411. // If no location is specified, a region will be chosen automatically.
  412. string parent = 1 [(google.api.field_behavior) = REQUIRED];
  413. // Required. Input/Output information each purchase model, such as file paths
  414. // and data formats.
  415. repeated AsyncModelConfig model_configs = 2
  416. [(google.api.field_behavior) = REQUIRED];
  417. }
  418. // Response to a `BatchOptimizeToursRequest`. This is returned in
  419. // the LRO Operation after the operation is complete.
  420. message BatchOptimizeToursResponse {}
  421. // A shipment model contains a set of shipments which must be performed by a
  422. // set of vehicles, while minimizing the overall cost, which is the sum of:
  423. //
  424. // * the cost of routing the vehicles (sum of cost per total time, cost per
  425. // travel time, and fixed cost over all vehicles).
  426. // * the unperformed shipment penalties.
  427. // * the cost of the global duration of the shipments
  428. message ShipmentModel {
  429. // Specifies a duration and distance matrix from visit and vehicle start
  430. // locations to visit and vehicle end locations.
  431. message DurationDistanceMatrix {
  432. // Specifies a row of the duration and distance matrix.
  433. message Row {
  434. // Duration values for a given row. It must have as many elements as
  435. // [ShipmentModel.duration_distance_matrix_dst_tags][google.cloud.optimization.v1.ShipmentModel.duration_distance_matrix_dst_tags].
  436. repeated google.protobuf.Duration durations = 1;
  437. // Distance values for a given row. If no costs or constraints refer to
  438. // distances in the model, this can be left empty; otherwise it must have
  439. // as many elements as `durations`.
  440. repeated double meters = 2;
  441. }
  442. // Specifies the rows of the duration and distance matrix. It must have as
  443. // many elements as
  444. // [ShipmentModel.duration_distance_matrix_src_tags][google.cloud.optimization.v1.ShipmentModel.duration_distance_matrix_src_tags].
  445. repeated Row rows = 1;
  446. // Tag defining to which vehicles this duration and distance matrix applies.
  447. // If empty, this applies to all vehicles, and there can only be a single
  448. // matrix.
  449. //
  450. // Each vehicle start must match exactly one matrix, i.e. exactly one of
  451. // their `start_tags` field must match the `vehicle_start_tag` of a matrix
  452. // (and of that matrix only).
  453. //
  454. // All matrices must have a different `vehicle_start_tag`.
  455. string vehicle_start_tag = 2;
  456. }
  457. // A precedence rule between two events (each event is the pickup or the
  458. // delivery of a shipment): the "second" event has to start at least
  459. // `offset_duration` after "first" has started.
  460. //
  461. // Several precedences can refer to the same (or related) events, e.g.,
  462. // "pickup of B happens after delivery of A" and "pickup of C happens after
  463. // pickup of B".
  464. //
  465. // Furthermore, precedences only apply when both shipments are performed and
  466. // are otherwise ignored.
  467. message PrecedenceRule {
  468. // Shipment index of the "first" event. This field must be specified.
  469. optional int32 first_index = 1;
  470. // Indicates if the "first" event is a delivery.
  471. bool first_is_delivery = 3;
  472. // Shipment index of the "second" event. This field must be specified.
  473. optional int32 second_index = 2;
  474. // Indicates if the "second" event is a delivery.
  475. bool second_is_delivery = 4;
  476. // The offset between the "first" and "second" event. It can be negative.
  477. google.protobuf.Duration offset_duration = 5;
  478. }
  479. // Deprecated: Use top level [BreakRule][] instead.
  480. // Rules to generate time breaks for a vehicle (e.g. lunch
  481. // breaks). A break is a contiguous period of time during which the vehicle
  482. // remains idle at its current position and cannot perform any visit. A break
  483. // may occur:
  484. //
  485. // * during the travel between two visits (which includes the time right
  486. // before or right after a visit, but not in the middle of a visit), in
  487. // which case it extends the corresponding transit time between the visits,
  488. // * or before the vehicle start (the vehicle may not start in the middle of
  489. // a break), in which case it does not affect the vehicle start time.
  490. // * or after the vehicle end (ditto, with the vehicle end time).
  491. message BreakRule {
  492. option deprecated = true;
  493. // The sequence of breaks (i.e. their number and order) that apply to each
  494. // vehicle must be known beforehand. The repeated `BreakRequest`s define
  495. // that sequence, in the order in which they must occur. Their time windows
  496. // (`earliest_start_time` / `latest_start_time`) may overlap, but they must
  497. // be compatible with the order (this is checked).
  498. message BreakRequest {
  499. // Required. Lower bound (inclusive) on the start of the break.
  500. google.protobuf.Timestamp earliest_start_time = 1
  501. [(google.api.field_behavior) = REQUIRED];
  502. // Required. Upper bound (inclusive) on the start of the break.
  503. google.protobuf.Timestamp latest_start_time = 2
  504. [(google.api.field_behavior) = REQUIRED];
  505. // Required. Minimum duration of the break. Must be positive.
  506. google.protobuf.Duration min_duration = 3
  507. [(google.api.field_behavior) = REQUIRED];
  508. }
  509. // One may further constrain the frequency and duration of the breaks
  510. // specified above, by enforcing a minimum break frequency, such as
  511. // "There must be a break of at least 1 hour every 12 hours". Assuming that
  512. // this can be interpreted as "Within any sliding time window of 12h, there
  513. // must be at least one break of at least one hour", that example would
  514. // translate to the following `FrequencyConstraint`:
  515. // ```
  516. // {
  517. // min_break_duration { seconds: 3600 } # 1 hour.
  518. // max_inter_break_duration { seconds: 39600 } # 11 hours (12 - 1 = 11).
  519. // }
  520. // ```
  521. //
  522. // The timing and duration of the breaks in the solution will respect all
  523. // such constraints, in addition to the time windows and minimum durations
  524. // already specified in the `BreakRequest`.
  525. //
  526. // A `FrequencyConstraint` may in practice apply to non-consecutive breaks.
  527. // For example, the following schedule honors the "1h every 12h" example:
  528. // ```
  529. // 04:00 vehicle start
  530. // .. performing travel and visits ..
  531. // 09:00 1 hour break
  532. // 10:00 end of the break
  533. // .. performing travel and visits ..
  534. // 12:00 20-min lunch break
  535. // 12:20 end of the break
  536. // .. performing travel and visits ..
  537. // 21:00 1 hour break
  538. // 22:00 end of the break
  539. // .. performing travel and visits ..
  540. // 23:59 vehicle end
  541. // ```
  542. message FrequencyConstraint {
  543. // Required. Minimum break duration for this constraint. Nonnegative.
  544. // See description of `FrequencyConstraint`.
  545. google.protobuf.Duration min_break_duration = 1
  546. [(google.api.field_behavior) = REQUIRED];
  547. // Required. Maximum allowed span of any interval of time in the route
  548. // that does not include at least partially a break of `duration >=
  549. // min_break_duration`. Must be positive.
  550. google.protobuf.Duration max_inter_break_duration = 2
  551. [(google.api.field_behavior) = REQUIRED];
  552. }
  553. // Sequence of breaks. See the `BreakRequest` message.
  554. repeated BreakRequest break_requests = 1;
  555. // Several `FrequencyConstraint` may apply. They must all be satisfied by
  556. // the `BreakRequest`s of this `BreakRule`. See `FrequencyConstraint`.
  557. repeated FrequencyConstraint frequency_constraints = 2;
  558. }
  559. // Set of shipments which must be performed in the model.
  560. repeated Shipment shipments = 1;
  561. // Set of vehicles which can be used to perform visits.
  562. repeated Vehicle vehicles = 2;
  563. // Constrains the maximum number of active vehicles. A vehicle is active if
  564. // its route performs at least one shipment. This can be used to limit the
  565. // number of routes in the case where there are fewer drivers than
  566. // vehicles and that the fleet of vehicles is heterogeneous. The optimization
  567. // will then select the best subset of vehicles to use.
  568. // Must be strictly positive.
  569. optional int32 max_active_vehicles = 4;
  570. // Global start and end time of the model: no times outside of this range
  571. // can be considered valid.
  572. //
  573. // The model's time span must be less than a year, i.e. the `global_end_time`
  574. // and the `global_start_time` must be within 31536000 seconds of each other.
  575. //
  576. // When using `cost_per_*hour` fields, you might want to set this window to a
  577. // smaller interval to increase performance (eg. if you model a single day,
  578. // you should set the global time limits to that day).
  579. // If unset, 00:00:00 UTC, January 1, 1970 (i.e. seconds: 0, nanos: 0) is used
  580. // as default.
  581. google.protobuf.Timestamp global_start_time = 5;
  582. // If unset, 00:00:00 UTC, January 1, 1971 (i.e. seconds: 31536000, nanos: 0)
  583. // is used as default.
  584. google.protobuf.Timestamp global_end_time = 6;
  585. // The "global duration" of the overall plan is the difference between the
  586. // earliest effective start time and the latest effective end time of
  587. // all vehicles. Users can assign a cost per hour to that quantity to try
  588. // and optimize for earliest job completion, for example. This cost must be in
  589. // the same unit as
  590. // [Shipment.penalty_cost][google.cloud.optimization.v1.Shipment.penalty_cost].
  591. double global_duration_cost_per_hour = 7;
  592. // Specifies duration and distance matrices used in the model. If this field
  593. // is empty, Google Maps or geodesic distances will be used instead, depending
  594. // on the value of the `use_geodesic_distances` field. If it is not empty,
  595. // `use_geodesic_distances` cannot be true and neither
  596. // `duration_distance_matrix_src_tags` nor `duration_distance_matrix_dst_tags`
  597. // can be empty.
  598. //
  599. // Usage examples:
  600. //
  601. // * There are two locations: locA and locB.
  602. // * 1 vehicle starting its route at locA and ending it at locA.
  603. // * 1 pickup visit request at locB.
  604. //
  605. // ```
  606. // model {
  607. // vehicles { start_tags: "locA" end_tags: "locA" }
  608. // shipments { pickups { tags: "locB" } }
  609. // duration_distance_matrix_src_tags: "locA"
  610. // duration_distance_matrix_src_tags: "locB"
  611. // duration_distance_matrix_dst_tags: "locA"
  612. // duration_distance_matrix_dst_tags: "locB"
  613. // duration_distance_matrices {
  614. // rows { # from: locA
  615. // durations { seconds: 0 } meters: 0 # to: locA
  616. // durations { seconds: 100 } meters: 1000 # to: locB
  617. // }
  618. // rows { # from: locB
  619. // durations { seconds: 102 } meters: 990 # to: locA
  620. // durations { seconds: 0 } meters: 0 # to: locB
  621. // }
  622. // }
  623. // }
  624. // ```
  625. //
  626. //
  627. // * There are three locations: locA, locB and locC.
  628. // * 1 vehicle starting its route at locA and ending it at locB, using
  629. // matrix "fast".
  630. // * 1 vehicle starting its route at locB and ending it at locB, using
  631. // matrix "slow".
  632. // * 1 vehicle starting its route at locB and ending it at locB, using
  633. // matrix "fast".
  634. // * 1 pickup visit request at locC.
  635. //
  636. // ```
  637. // model {
  638. // vehicles { start_tags: "locA" end_tags: "locB" start_tags: "fast" }
  639. // vehicles { start_tags: "locB" end_tags: "locB" start_tags: "slow" }
  640. // vehicles { start_tags: "locB" end_tags: "locB" start_tags: "fast" }
  641. // shipments { pickups { tags: "locC" } }
  642. // duration_distance_matrix_src_tags: "locA"
  643. // duration_distance_matrix_src_tags: "locB"
  644. // duration_distance_matrix_src_tags: "locC"
  645. // duration_distance_matrix_dst_tags: "locB"
  646. // duration_distance_matrix_dst_tags: "locC"
  647. // duration_distance_matrices {
  648. // vehicle_start_tag: "fast"
  649. // rows { # from: locA
  650. // durations { seconds: 1000 } meters: 2000 # to: locB
  651. // durations { seconds: 600 } meters: 1000 # to: locC
  652. // }
  653. // rows { # from: locB
  654. // durations { seconds: 0 } meters: 0 # to: locB
  655. // durations { seconds: 700 } meters: 1200 # to: locC
  656. // }
  657. // rows { # from: locC
  658. // durations { seconds: 702 } meters: 1190 # to: locB
  659. // durations { seconds: 0 } meters: 0 # to: locC
  660. // }
  661. // }
  662. // duration_distance_matrices {
  663. // vehicle_start_tag: "slow"
  664. // rows { # from: locA
  665. // durations { seconds: 1800 } meters: 2001 # to: locB
  666. // durations { seconds: 900 } meters: 1002 # to: locC
  667. // }
  668. // rows { # from: locB
  669. // durations { seconds: 0 } meters: 0 # to: locB
  670. // durations { seconds: 1000 } meters: 1202 # to: locC
  671. // }
  672. // rows { # from: locC
  673. // durations { seconds: 1001 } meters: 1195 # to: locB
  674. // durations { seconds: 0 } meters: 0 # to: locC
  675. // }
  676. // }
  677. // }
  678. // ```
  679. repeated DurationDistanceMatrix duration_distance_matrices = 8;
  680. // Tags defining the sources of the duration and distance matrices;
  681. // `duration_distance_matrices(i).rows(j)` defines durations and distances
  682. // from visits with tag `duration_distance_matrix_src_tags(j)` to other visits
  683. // in matrix i.
  684. //
  685. // Tags correspond to
  686. // [VisitRequest.tags][google.cloud.optimization.v1.Shipment.VisitRequest.tags]
  687. // or [Vehicle.start_tags][google.cloud.optimization.v1.Vehicle.start_tags].
  688. // A given `VisitRequest` or `Vehicle` must match exactly one tag in this
  689. // field. Note that a `Vehicle`'s source, destination and matrix tags may be
  690. // the same; similarly a `VisitRequest`'s source and destination tags may be
  691. // the same. All tags must be different and cannot be empty strings. If this
  692. // field is not empty, then `duration_distance_matrices` must not be empty.
  693. repeated string duration_distance_matrix_src_tags = 9;
  694. // Tags defining the destinations of the duration and distance matrices;
  695. // `duration_distance_matrices(i).rows(j).durations(k)` (resp.
  696. // `duration_distance_matrices(i).rows(j).meters(k))` defines the duration
  697. // (resp. the distance) of the travel from visits with tag
  698. // `duration_distance_matrix_src_tags(j)` to visits with tag
  699. // `duration_distance_matrix_dst_tags(k)` in matrix i.
  700. //
  701. // Tags correspond to
  702. // [VisitRequest.tags][google.cloud.optimization.v1.Shipment.VisitRequest.tags]
  703. // or [Vehicle.start_tags][google.cloud.optimization.v1.Vehicle.start_tags].
  704. // A given `VisitRequest` or `Vehicle` must match exactly one tag in this
  705. // field. Note that a `Vehicle`'s source, destination and matrix tags may be
  706. // the same; similarly a `VisitRequest`'s source and destination tags may be
  707. // the same. All tags must be different and cannot be empty strings. If this
  708. // field is not empty, then `duration_distance_matrices` must not be empty.
  709. repeated string duration_distance_matrix_dst_tags = 10;
  710. // Transition attributes added to the model.
  711. repeated TransitionAttributes transition_attributes = 11;
  712. // Sets of incompatible shipment_types (see `ShipmentTypeIncompatibility`).
  713. repeated ShipmentTypeIncompatibility shipment_type_incompatibilities = 12;
  714. // Sets of `shipment_type` requirements (see `ShipmentTypeRequirement`).
  715. repeated ShipmentTypeRequirement shipment_type_requirements = 13;
  716. // Set of precedence rules which must be enforced in the model.
  717. repeated PrecedenceRule precedence_rules = 14;
  718. // Deprecated: No longer used.
  719. // Set of break rules used in the model.
  720. // Each vehicle specifies the `BreakRule` that applies to it via the
  721. // [Vehicle.break_rule_indices][google.cloud.optimization.v1.Vehicle.break_rule_indices]
  722. // field (which must be a singleton).
  723. repeated BreakRule break_rules = 15 [deprecated = true];
  724. }
  725. // The shipment of a single item, from one of its pickups to one of its
  726. // deliveries. For the shipment to be considered as performed, a unique vehicle
  727. // must visit one of its pickup locations (and decrease its spare capacities
  728. // accordingly), then visit one of its delivery locations later on (and
  729. // therefore re-increase its spare capacities accordingly).
  730. message Shipment {
  731. // Request for a visit which can be done by a vehicle: it has a geo-location
  732. // (or two, see below), opening and closing times represented by time windows,
  733. // and a service duration time (time spent by the vehicle once it has arrived
  734. // to pickup or drop off goods).
  735. message VisitRequest {
  736. // The geo-location where the vehicle arrives when performing this
  737. // `VisitRequest`. If the shipment model has duration distance matrices,
  738. // `arrival_location` must not be specified.
  739. google.type.LatLng arrival_location = 1;
  740. // The waypoint where the vehicle arrives when performing this
  741. // `VisitRequest`. If the shipment model has duration distance matrices,
  742. // `arrival_waypoint` must not be specified.
  743. Waypoint arrival_waypoint = 2;
  744. // The geo-location where the vehicle departs after completing this
  745. // `VisitRequest`. Can be omitted if it is the same as `arrival_location`.
  746. // If the shipment model has duration distance matrices,
  747. // `departure_location` must not be specified.
  748. google.type.LatLng departure_location = 3;
  749. // The waypoint where the vehicle departs after completing this
  750. // `VisitRequest`. Can be omitted if it is the same as `arrival_waypoint`.
  751. // If the shipment model has duration distance matrices,
  752. // `departure_waypoint` must not be specified.
  753. Waypoint departure_waypoint = 4;
  754. // Specifies tags attached to the visit request.
  755. // Empty or duplicate strings are not allowed.
  756. repeated string tags = 5;
  757. // Time windows which constrain the arrival time at a visit.
  758. // Note that a vehicle may depart outside of the arrival time window, i.e.
  759. // arrival time + duration do not need to be inside a time window. This can
  760. // result in waiting time if the vehicle arrives before
  761. // [TimeWindow.start_time][google.cloud.optimization.v1.TimeWindow.start_time].
  762. //
  763. // The absence of `TimeWindow` means that the vehicle can perform this visit
  764. // at any time.
  765. //
  766. // Time windows must be disjoint, i.e. no time window must overlap with or
  767. // be adjacent to another, and they must be in increasing order.
  768. //
  769. // `cost_per_hour_after_soft_end_time` and `soft_end_time` can only
  770. // be set if there is a single time window.
  771. repeated TimeWindow time_windows = 6;
  772. // Duration of the visit, i.e. time spent by the vehicle between arrival
  773. // and departure (to be added to the possible waiting time; see
  774. // `time_windows`).
  775. google.protobuf.Duration duration = 7;
  776. // Cost to service this visit request on a vehicle route. This can be used
  777. // to pay different costs for each alternative pickup or delivery of a
  778. // shipment. This cost must be in the same unit as `Shipment.penalty_cost`
  779. // and must not be negative.
  780. double cost = 8;
  781. // Load demands of this visit request. This is just like
  782. // [Shipment.load_demands][google.cloud.optimization.v1.Shipment.load_demands]
  783. // field, except that it only applies to this
  784. // [VisitRequest][google.cloud.optimization.v1.Shipment.VisitRequest]
  785. // instead of the whole [Shipment][google.cloud.optimization.v1.Shipment].
  786. // The demands listed here are added to the demands listed in
  787. // [Shipment.load_demands][google.cloud.optimization.v1.Shipment.load_demands].
  788. map<string, Load> load_demands = 12;
  789. // Specifies the types of the visit. This may be used to allocate additional
  790. // time required for a vehicle to complete this visit (see
  791. // [Vehicle.extra_visit_duration_for_visit_type][google.cloud.optimization.v1.Vehicle.extra_visit_duration_for_visit_type]).
  792. //
  793. // A type can only appear once.
  794. repeated string visit_types = 10;
  795. // Specifies a label for this `VisitRequest`. This label is reported in the
  796. // response as `visit_label` in the corresponding
  797. // [ShipmentRoute.Visit][google.cloud.optimization.v1.ShipmentRoute.Visit].
  798. string label = 11;
  799. // Deprecated: Use [VisitRequest.load_demands][] instead.
  800. repeated CapacityQuantity demands = 9 [deprecated = true];
  801. }
  802. // When performing a visit, a predefined amount may be added to the vehicle
  803. // load if it's a pickup, or subtracted if it's a delivery. This message
  804. // defines such amount. See
  805. // [load_demands][google.cloud.optimization.v1.Shipment.load_demands].
  806. message Load {
  807. // The amount by which the load of the vehicle performing the corresponding
  808. // visit will vary. Since it is an integer, users are advised to choose an
  809. // appropriate unit to avoid loss of precision. Must be ≥ 0.
  810. int64 amount = 2;
  811. }
  812. // Set of pickup alternatives associated to the shipment. If not specified,
  813. // the vehicle only needs to visit a location corresponding to the deliveries.
  814. repeated VisitRequest pickups = 1;
  815. // Set of delivery alternatives associated to the shipment. If not specified,
  816. // the vehicle only needs to visit a location corresponding to the pickups.
  817. repeated VisitRequest deliveries = 2;
  818. // Load demands of the shipment (for example weight, volume, number of
  819. // pallets etc). The keys in the map should be identifiers describing the type
  820. // of the corresponding load, ideally also including the units.
  821. // For example: "weight_kg", "volume_gallons", "pallet_count", etc.
  822. // If a given key does not appear in the map, the corresponding load is
  823. // considered as null.
  824. map<string, Load> load_demands = 14;
  825. // If the shipment is not completed, this penalty is added to the overall
  826. // cost of the routes. A shipment is considered completed if one of its pickup
  827. // and delivery alternatives is visited. The cost may be expressed in the
  828. // same unit used for all other cost-related fields in the model and must be
  829. // positive.
  830. //
  831. // *IMPORTANT*: If this penalty is not specified, it is considered infinite,
  832. // i.e. the shipment must be completed.
  833. optional double penalty_cost = 4;
  834. // The set of vehicles that may perform this shipment. If empty, all vehicles
  835. // may perform it. Vehicles are given by their index in the `ShipmentModel`'s
  836. // `vehicles` list.
  837. repeated int32 allowed_vehicle_indices = 5;
  838. // Specifies the cost that is incurred when this shipment is delivered by each
  839. // vehicle. If specified, it must have EITHER:
  840. //
  841. // * the same number of elements as `costs_per_vehicle_indices`.
  842. // `costs_per_vehicle[i]` corresponds to vehicle
  843. // `costs_per_vehicle_indices[i]` of the model.
  844. // * the same number of elements as there are vehicles in the model. The
  845. // i-th element corresponds to vehicle #i of the model.
  846. //
  847. // These costs must be in the same unit as `penalty_cost` and must not be
  848. // negative. Leave this field empty, if there are no such costs.
  849. repeated double costs_per_vehicle = 6;
  850. // Indices of the vehicles to which `costs_per_vehicle` applies. If non-empty,
  851. // it must have the same number of elements as `costs_per_vehicle`. A vehicle
  852. // index may not be specified more than once. If a vehicle is excluded from
  853. // `costs_per_vehicle_indices`, its cost is zero.
  854. repeated int32 costs_per_vehicle_indices = 7;
  855. // Specifies the maximum relative detour time compared to the shortest path
  856. // from pickup to delivery. If specified, it must be nonnegative, and the
  857. // shipment must contain at least a pickup and a delivery.
  858. //
  859. // For example, let t be the shortest time taken to go from the selected
  860. // pickup alternative directly to the selected delivery alternative. Then
  861. // setting `pickup_to_delivery_relative_detour_limit` enforces:
  862. //
  863. // ```
  864. // start_time(delivery) - start_time(pickup) <=
  865. // std::ceil(t * (1.0 + pickup_to_delivery_relative_detour_limit))
  866. // ```
  867. //
  868. // If both relative and absolute limits are specified on the same shipment,
  869. // the more constraining limit is used for each possible pickup/delivery pair.
  870. // As of 2017/10, detours are only supported when travel durations do not
  871. // depend on vehicles.
  872. optional double pickup_to_delivery_relative_detour_limit = 8;
  873. // Specifies the maximum absolute detour time compared to the shortest path
  874. // from pickup to delivery. If specified, it must be nonnegative, and the
  875. // shipment must contain at least a pickup and a delivery.
  876. //
  877. // For example, let t be the shortest time taken to go from the selected
  878. // pickup alternative directly to the selected delivery alternative. Then
  879. // setting `pickup_to_delivery_absolute_detour_limit` enforces:
  880. //
  881. // ```
  882. // start_time(delivery) - start_time(pickup) <=
  883. // t + pickup_to_delivery_absolute_detour_limit
  884. // ```
  885. //
  886. // If both relative and absolute limits are specified on the same shipment,
  887. // the more constraining limit is used for each possible pickup/delivery pair.
  888. // As of 2017/10, detours are only supported when travel durations do not
  889. // depend on vehicles.
  890. google.protobuf.Duration pickup_to_delivery_absolute_detour_limit = 9;
  891. // Specifies the maximum duration from start of pickup to start of delivery of
  892. // a shipment. If specified, it must be nonnegative, and the shipment must
  893. // contain at least a pickup and a delivery. This does not depend on which
  894. // alternatives are selected for pickup and delivery, nor on vehicle speed.
  895. // This can be specified alongside maximum detour constraints: the solution
  896. // will respect both specifications.
  897. google.protobuf.Duration pickup_to_delivery_time_limit = 10;
  898. // Non-empty string specifying a "type" for this shipment.
  899. // This feature can be used to define incompatibilities or requirements
  900. // between `shipment_types` (see `shipment_type_incompatibilities` and
  901. // `shipment_type_requirements` in `ShipmentModel`).
  902. //
  903. // Differs from `visit_types` which is specified for a single visit: All
  904. // pickup/deliveries belonging to the same shipment share the same
  905. // `shipment_type`.
  906. string shipment_type = 11;
  907. // Specifies a label for this shipment. This label is reported in the response
  908. // in the `shipment_label` of the corresponding
  909. // [ShipmentRoute.Visit][google.cloud.optimization.v1.ShipmentRoute.Visit].
  910. string label = 12;
  911. // If true, skip this shipment, but don't apply a `penalty_cost`.
  912. //
  913. // Ignoring a shipment results in a validation error when there are any
  914. // `shipment_type_requirements` in the model.
  915. //
  916. // Ignoring a shipment that is performed in `injected_first_solution_routes`
  917. // or `injected_solution_constraint` is permitted; the solver removes the
  918. // related pickup/delivery visits from the performing route.
  919. // `precedence_rules` that reference ignored shipments will also be ignored.
  920. bool ignore = 13;
  921. // Deprecated: Use [Shipment.load_demands][] instead.
  922. repeated CapacityQuantity demands = 3 [deprecated = true];
  923. }
  924. // Specifies incompatibilties between shipments depending on their
  925. // shipment_type. The appearance of incompatible shipments on the same route is
  926. // restricted based on the incompatibility mode.
  927. message ShipmentTypeIncompatibility {
  928. // Modes defining how the appearance of incompatible shipments are restricted
  929. // on the same route.
  930. enum IncompatibilityMode {
  931. // Unspecified incompatibility mode. This value should never be used.
  932. INCOMPATIBILITY_MODE_UNSPECIFIED = 0;
  933. // In this mode, two shipments with incompatible types can never share the
  934. // same vehicle.
  935. NOT_PERFORMED_BY_SAME_VEHICLE = 1;
  936. // For two shipments with incompatible types with the
  937. // `NOT_IN_SAME_VEHICLE_SIMULTANEOUSLY` incompatibility mode:
  938. //
  939. // * If both are pickups only (no deliveries) or deliveries only (no
  940. // pickups), they cannot share the same vehicle at all.
  941. // * If one of the shipments has a delivery and the other a pickup, the two
  942. // shipments can share the same vehicle iff the former shipment is
  943. // delivered before the latter is picked up.
  944. NOT_IN_SAME_VEHICLE_SIMULTANEOUSLY = 2;
  945. }
  946. // List of incompatible types. Two shipments having different `shipment_types`
  947. // among those listed are "incompatible".
  948. repeated string types = 1;
  949. // Mode applied to the incompatibility.
  950. IncompatibilityMode incompatibility_mode = 2;
  951. }
  952. // Specifies requirements between shipments based on their shipment_type.
  953. // The specifics of the requirement are defined by the requirement mode.
  954. message ShipmentTypeRequirement {
  955. // Modes defining the appearance of dependent shipments on a route.
  956. enum RequirementMode {
  957. // Unspecified requirement mode. This value should never be used.
  958. REQUIREMENT_MODE_UNSPECIFIED = 0;
  959. // In this mode, all "dependent" shipments must share the same vehicle as at
  960. // least one of their "required" shipments.
  961. PERFORMED_BY_SAME_VEHICLE = 1;
  962. // With the `IN_SAME_VEHICLE_AT_PICKUP_TIME` mode, all "dependent"
  963. // shipments need to have at least one "required" shipment on their vehicle
  964. // at the time of their pickup.
  965. //
  966. // A "dependent" shipment pickup must therefore have either:
  967. //
  968. // * A delivery-only "required" shipment delivered on the route after, or
  969. // * A "required" shipment picked up on the route before it, and if the
  970. // "required" shipment has a delivery, this delivery must be performed
  971. // after the "dependent" shipment's pickup.
  972. IN_SAME_VEHICLE_AT_PICKUP_TIME = 2;
  973. // Same as before, except the "dependent" shipments need to have a
  974. // "required" shipment on their vehicle at the time of their *delivery*.
  975. IN_SAME_VEHICLE_AT_DELIVERY_TIME = 3;
  976. }
  977. // List of alternative shipment types required by the
  978. // `dependent_shipment_types`.
  979. repeated string required_shipment_type_alternatives = 1;
  980. // All shipments with a type in the `dependent_shipment_types` field require
  981. // at least one shipment of type `required_shipment_type_alternatives` to be
  982. // visited on the same route.
  983. //
  984. // NOTE: Chains of requirements such that a `shipment_type` depends on itself
  985. // are not allowed.
  986. repeated string dependent_shipment_types = 2;
  987. // Mode applied to the requirement.
  988. RequirementMode requirement_mode = 3;
  989. }
  990. // Models a vehicle in a shipment problem. Solving a shipment problem will
  991. // build a route starting from `start_location` and ending at `end_location`
  992. // for this vehicle. A route is a sequence of visits (see `ShipmentRoute`).
  993. message Vehicle {
  994. // Travel modes which can be used by vehicles.
  995. //
  996. // These should be a subset of the Google Maps Platform Routes Preferred API
  997. // travel modes, see:
  998. // https://developers.google.com/maps/documentation/routes_preferred/reference/rest/Shared.Types/RouteTravelMode.
  999. enum TravelMode {
  1000. // Unspecified travel mode, equivalent to `DRIVING`.
  1001. TRAVEL_MODE_UNSPECIFIED = 0;
  1002. // Travel mode corresponding to driving directions (car, ...).
  1003. DRIVING = 1;
  1004. }
  1005. // Policy on how a vehicle can be unloaded. Applies only to shipments having
  1006. // both a pickup and a delivery.
  1007. //
  1008. // Other shipments are free to occur anywhere on the route independent of
  1009. // `unloading_policy`.
  1010. enum UnloadingPolicy {
  1011. // Unspecified unloading policy; deliveries must just occur after their
  1012. // corresponding pickups.
  1013. UNLOADING_POLICY_UNSPECIFIED = 0;
  1014. // Deliveries must occur in reverse order of pickups
  1015. LAST_IN_FIRST_OUT = 1;
  1016. // Deliveries must occur in the same order as pickups
  1017. FIRST_IN_FIRST_OUT = 2;
  1018. }
  1019. // Defines a load limit applying to a vehicle, e.g. "this truck may only
  1020. // carry up to 3500 kg". See
  1021. // [load_limits][google.cloud.optimization.v1.Vehicle.load_limits].
  1022. message LoadLimit {
  1023. // Interval of acceptable load amounts.
  1024. message Interval {
  1025. // A minimum acceptable load. Must be ≥ 0.
  1026. // If they're both specified,
  1027. // [min][google.cloud.optimization.v1.Vehicle.LoadLimit.Interval.min] must
  1028. // be ≤
  1029. // [max][google.cloud.optimization.v1.Vehicle.LoadLimit.Interval.max].
  1030. int64 min = 1;
  1031. // A maximum acceptable load. Must be ≥ 0. If unspecified, the maximum
  1032. // load is unrestricted by this message.
  1033. // If they're both specified,
  1034. // [min][google.cloud.optimization.v1.Vehicle.LoadLimit.Interval.min] must
  1035. // be ≤
  1036. // [max][google.cloud.optimization.v1.Vehicle.LoadLimit.Interval.max].
  1037. optional int64 max = 2;
  1038. }
  1039. // The maximum acceptable amount of load.
  1040. optional int64 max_load = 1;
  1041. // A soft limit of the load. See
  1042. // [cost_per_unit_above_soft_max][google.cloud.optimization.v1.Vehicle.LoadLimit.cost_per_unit_above_soft_max].
  1043. int64 soft_max_load = 2;
  1044. // If the load ever exceeds
  1045. // [soft_max_load][google.cloud.optimization.v1.Vehicle.LoadLimit.soft_max_load]
  1046. // along this vehicle's route, the following cost penalty applies (only once
  1047. // per vehicle): (load -
  1048. // [soft_max_load][google.cloud.optimization.v1.Vehicle.LoadLimit.soft_max_load])
  1049. // * [cost_per_unit_above_soft_max][google.cloud.optimization.v1.Vehicle.LoadLimit.cost_per_unit_above_soft_max]. All costs
  1050. // add up and must be in the same unit as
  1051. // [Shipment.penalty_cost][google.cloud.optimization.v1.Shipment.penalty_cost].
  1052. double cost_per_unit_above_soft_max = 3;
  1053. // The acceptable load interval of the vehicle at the start of the route.
  1054. Interval start_load_interval = 4;
  1055. // The acceptable load interval of the vehicle at the end of the route.
  1056. Interval end_load_interval = 5;
  1057. }
  1058. // A limit defining a maximum duration of the route of a vehicle. It can be
  1059. // either hard or soft.
  1060. //
  1061. // When a soft limit field is defined, both the soft max threshold and its
  1062. // associated cost must be defined together.
  1063. message DurationLimit {
  1064. // A hard limit constraining the duration to be at most max_duration.
  1065. google.protobuf.Duration max_duration = 1;
  1066. // A soft limit not enforcing a maximum duration limit, but when violated
  1067. // makes the route incur a cost. This cost adds up to other costs defined in
  1068. // the model, with the same unit.
  1069. //
  1070. // If defined, `soft_max_duration` must be nonnegative. If max_duration is
  1071. // also defined, `soft_max_duration` must be less than max_duration.
  1072. google.protobuf.Duration soft_max_duration = 2;
  1073. // Cost per hour incurred if the `soft_max_duration` threshold is violated.
  1074. // The additional cost is 0 if the duration is under the threshold,
  1075. // otherwise the cost depends on the duration as follows:
  1076. // ```
  1077. // cost_per_hour_after_soft_max * (duration - soft_max_duration)
  1078. // ```
  1079. // The cost must be nonnegative.
  1080. optional double cost_per_hour_after_soft_max = 3;
  1081. // A soft limit not enforcing a maximum duration limit, but when violated
  1082. // makes the route incur a cost, quadratic in the duration. This cost adds
  1083. // up to other costs defined in the model, with the same unit.
  1084. //
  1085. // If defined, `quadratic_soft_max_duration` must be nonnegative. If
  1086. // `max_duration` is also defined, `quadratic_soft_max_duration` must be
  1087. // less than `max_duration`, and the difference must be no larger than one
  1088. // day:
  1089. //
  1090. // `max_duration - quadratic_soft_max_duration <= 86400 seconds`
  1091. google.protobuf.Duration quadratic_soft_max_duration = 4;
  1092. // Cost per square hour incurred if the
  1093. // `quadratic_soft_max_duration` threshold is violated.
  1094. //
  1095. // The additional cost is 0 if the duration is under the threshold,
  1096. // otherwise the cost depends on the duration as follows:
  1097. //
  1098. // ```
  1099. // cost_per_square_hour_after_quadratic_soft_max *
  1100. // (duration - quadratic_soft_max_duration)^2
  1101. // ```
  1102. //
  1103. // The cost must be nonnegative.
  1104. optional double cost_per_square_hour_after_quadratic_soft_max = 5;
  1105. }
  1106. // The travel mode which affects the roads usable by the vehicle and its
  1107. // speed. See also `travel_duration_multiple`.
  1108. TravelMode travel_mode = 1;
  1109. // Geographic location where the vehicle starts before picking up any
  1110. // shipments. If not specified, the vehicle starts at its first pickup.
  1111. // If the shipment model has duration and distance matrices, `start_location`
  1112. // must not be specified.
  1113. google.type.LatLng start_location = 3;
  1114. // Waypoint representing a geographic location where the vehicle starts before
  1115. // picking up any shipments. If neither `start_waypoint` nor `start_location`
  1116. // is specified, the vehicle starts at its first pickup.
  1117. // If the shipment model has duration and distance matrices, `start_waypoint`
  1118. // must not be specified.
  1119. Waypoint start_waypoint = 4;
  1120. // Geographic location where the vehicle ends after it has completed its last
  1121. // `VisitRequest`. If not specified the vehicle's `ShipmentRoute` ends
  1122. // immediately when it completes its last `VisitRequest`.
  1123. // If the shipment model has duration and distance matrices, `end_location`
  1124. // must not be specified.
  1125. google.type.LatLng end_location = 5;
  1126. // Waypoint representing a geographic location where the vehicle ends after
  1127. // it has completed its last `VisitRequest`. If neither `end_waypoint` nor
  1128. // `end_location` is specified, the vehicle's `ShipmentRoute` ends immediately
  1129. // when it completes its last `VisitRequest`.
  1130. // If the shipment model has duration and distance matrices, `end_waypoint`
  1131. // must not be specified.
  1132. Waypoint end_waypoint = 6;
  1133. // Specifies tags attached to the start of the vehicle's route.
  1134. //
  1135. // Empty or duplicate strings are not allowed.
  1136. repeated string start_tags = 7;
  1137. // Specifies tags attached to the end of the vehicle's route.
  1138. //
  1139. // Empty or duplicate strings are not allowed.
  1140. repeated string end_tags = 8;
  1141. // Time windows during which the vehicle may depart its start location.
  1142. // They must be within the global time limits (see
  1143. // [ShipmentModel.global_*][google.cloud.optimization.v1.ShipmentModel.global_start_time]
  1144. // fields). If unspecified, there is no limitation besides those global time
  1145. // limits.
  1146. //
  1147. // Time windows belonging to the same repeated field must be disjoint, i.e. no
  1148. // time window can overlap with or be adjacent to another, and they must be in
  1149. // chronological order.
  1150. //
  1151. // `cost_per_hour_after_soft_end_time` and `soft_end_time` can only be set if
  1152. // there is a single time window.
  1153. repeated TimeWindow start_time_windows = 9;
  1154. // Time windows during which the vehicle may arrive at its end location.
  1155. // They must be within the global time limits (see
  1156. // [ShipmentModel.global_*][google.cloud.optimization.v1.ShipmentModel.global_start_time]
  1157. // fields). If unspecified, there is no limitation besides those global time
  1158. // limits.
  1159. //
  1160. // Time windows belonging to the same repeated field must be disjoint, i.e. no
  1161. // time window can overlap with or be adjacent to another, and they must be in
  1162. // chronological order.
  1163. //
  1164. // `cost_per_hour_after_soft_end_time` and `soft_end_time` can only be set if
  1165. // there is a single time window.
  1166. repeated TimeWindow end_time_windows = 10;
  1167. // Specifies a multiplicative factor that can be used to increase or decrease
  1168. // travel times of this vehicle. For example, setting this to 2.0 means
  1169. // that this vehicle is slower and has travel times that are twice what they
  1170. // are for standard vehicles. This multiple does not affect visit durations.
  1171. // It does affect cost if `cost_per_hour` or `cost_per_traveled_hour` are
  1172. // specified. This must be in the range [0.001, 1000.0]. If unset, the vehicle
  1173. // is standard, and this multiple is considered 1.0.
  1174. //
  1175. // WARNING: Travel times will be rounded to the nearest second after this
  1176. // multiple is applied but before performing any numerical operations, thus,
  1177. // a small multiple may result in a loss of precision.
  1178. //
  1179. // See also `extra_visit_duration_for_visit_type` below.
  1180. optional double travel_duration_multiple = 11;
  1181. // Unloading policy enforced on the vehicle.
  1182. UnloadingPolicy unloading_policy = 12;
  1183. // Capacities of the vehicle (weight, volume, # of pallets for example).
  1184. // The keys in the map are the identifiers of the type of load, consistent
  1185. // with the keys of the
  1186. // [Shipment.load_demands][google.cloud.optimization.v1.Shipment.load_demands]
  1187. // field. If a given key is absent from this map, the corresponding capacity
  1188. // is considered to be limitless.
  1189. map<string, LoadLimit> load_limits = 30;
  1190. // Vehicle costs: all costs add up and must be in the same unit as
  1191. // [Shipment.penalty_cost][google.cloud.optimization.v1.Shipment.penalty_cost].
  1192. //
  1193. // Cost per hour of the vehicle route. This cost is applied to the total time
  1194. // taken by the route, and includes travel time, waiting time, and visit time.
  1195. // Using `cost_per_hour` instead of just `cost_per_traveled_hour` may result
  1196. // in additional latency.
  1197. double cost_per_hour = 16;
  1198. // Cost per traveled hour of the vehicle route. This cost is applied only to
  1199. // travel time taken by the route (i.e., that reported in
  1200. // [ShipmentRoute.transitions][google.cloud.optimization.v1.ShipmentRoute.transitions]),
  1201. // and excludes waiting time and visit time.
  1202. double cost_per_traveled_hour = 17;
  1203. // Cost per kilometer of the vehicle route. This cost is applied to the
  1204. // distance reported in the
  1205. // [ShipmentRoute.transitions][google.cloud.optimization.v1.ShipmentRoute.transitions]
  1206. // and does not apply to any distance implicitly traveled from the
  1207. // `arrival_location` to the `departure_location` of a single `VisitRequest`.
  1208. double cost_per_kilometer = 18;
  1209. // Fixed cost applied if this vehicle is used to handle a shipment.
  1210. double fixed_cost = 19;
  1211. // This field only applies to vehicles when their route does not serve any
  1212. // shipments. It indicates if the vehicle should be considered as used or not
  1213. // in this case.
  1214. //
  1215. // If true, the vehicle goes from its start to its end location even if it
  1216. // doesn't serve any shipments, and time and distance costs resulting from its
  1217. // start --> end travel are taken into account.
  1218. //
  1219. // Otherwise, it doesn't travel from its start to its end location, and no
  1220. // `break_rule` or delay (from `TransitionAttributes`) are scheduled for this
  1221. // vehicle. In this case, the vehicle's `ShipmentRoute` doesn't contain any
  1222. // information except for the vehicle index and label.
  1223. bool used_if_route_is_empty = 20;
  1224. // Limit applied to the total duration of the vehicle's route. In a given
  1225. // `OptimizeToursResponse`, the route duration of a vehicle is the
  1226. // difference between its `vehicle_end_time` and `vehicle_start_time`.
  1227. DurationLimit route_duration_limit = 21;
  1228. // Limit applied to the travel duration of the vehicle's route. In a given
  1229. // `OptimizeToursResponse`, the route travel duration is the sum of all its
  1230. // [transitions.travel_duration][google.cloud.optimization.v1.ShipmentRoute.Transition.travel_duration].
  1231. DurationLimit travel_duration_limit = 22;
  1232. // Limit applied to the total distance of the vehicle's route. In a given
  1233. // `OptimizeToursResponse`, the route distance is the sum of all its
  1234. // [transitions.travel_distance_meters][google.cloud.optimization.v1.ShipmentRoute.Transition.travel_distance_meters].
  1235. DistanceLimit route_distance_limit = 23;
  1236. // Specifies a map from visit_types strings to durations. The duration is time
  1237. // in addition to
  1238. // [VisitRequest.duration][google.cloud.optimization.v1.Shipment.VisitRequest.duration]
  1239. // to be taken at visits with the specified `visit_types`. This extra visit
  1240. // duration adds cost if `cost_per_hour` is specified. Keys (i.e.
  1241. // `visit_types`) cannot be empty strings.
  1242. //
  1243. // If a visit request has multiple types, a duration will be added for each
  1244. // type in the map.
  1245. map<string, google.protobuf.Duration> extra_visit_duration_for_visit_type =
  1246. 24;
  1247. // Describes the break schedule to be enforced on this vehicle.
  1248. // If empty, no breaks will be scheduled for this vehicle.
  1249. BreakRule break_rule = 25;
  1250. // Specifies a label for this vehicle. This label is reported in the response
  1251. // as the `vehicle_label` of the corresponding
  1252. // [ShipmentRoute][google.cloud.optimization.v1.ShipmentRoute].
  1253. string label = 27;
  1254. // If true, `used_if_route_is_empty` must be false, and this vehicle will
  1255. // remain unused.
  1256. //
  1257. // If a shipment is performed by an ignored vehicle in
  1258. // `injected_first_solution_routes`, it is skipped in the first solution but
  1259. // is free to be performed in the response.
  1260. //
  1261. // If a shipment is performed by an ignored vehicle in
  1262. // `injected_solution_constraint` and any related pickup/delivery is
  1263. // constrained to remain on the vehicle (i.e., not relaxed to level
  1264. // `RELAX_ALL_AFTER_THRESHOLD`), it is skipped in the response.
  1265. // If a shipment has a non-empty `allowed_vehicle_indices` field and all of
  1266. // the allowed vehicles are ignored, it is skipped in the response.
  1267. bool ignore = 28;
  1268. // Deprecated: No longer used.
  1269. // Indices in the `break_rule` field in the source
  1270. // [ShipmentModel][]. They correspond to break rules enforced on the vehicle.
  1271. //
  1272. //
  1273. // As of 2018/03, at most one rule index per vehicle can be specified.
  1274. repeated int32 break_rule_indices = 29 [deprecated = true];
  1275. // Deprecated: Use [Vehicle.load_limits][] instead.
  1276. repeated CapacityQuantity capacities = 13 [deprecated = true];
  1277. // Deprecated: Use [Vehicle.LoadLimit.start_load_interval][] instead.
  1278. repeated CapacityQuantityInterval start_load_intervals = 14
  1279. [deprecated = true];
  1280. // Deprecated: Use [Vehicle.LoadLimit.end_load_interval][] instead.
  1281. repeated CapacityQuantityInterval end_load_intervals = 15 [deprecated = true];
  1282. }
  1283. // Time windows constrain the time of an event, such as the arrival time at a
  1284. // visit, or the start and end time of a vehicle.
  1285. //
  1286. // Hard time window bounds, `start_time` and `end_time`, enforce the earliest
  1287. // and latest time of the event, such that `start_time <= event_time <=
  1288. // end_time`. The soft time window lower bound, `soft_start_time`, expresses a
  1289. // preference for the event to happen at or after `soft_start_time` by incurring
  1290. // a cost proportional to how long before soft_start_time the event occurs. The
  1291. // soft time window upper bound, `soft_end_time`, expresses a preference for the
  1292. // event to happen at or before `soft_end_time` by incurring a cost proportional
  1293. // to how long after `soft_end_time` the event occurs. `start_time`, `end_time`,
  1294. // `soft_start_time` and `soft_end_time` should be within the global time limits
  1295. // (see
  1296. // [ShipmentModel.global_start_time][google.cloud.optimization.v1.ShipmentModel.global_start_time]
  1297. // and
  1298. // [ShipmentModel.global_end_time][google.cloud.optimization.v1.ShipmentModel.global_end_time])
  1299. // and should respect:
  1300. // ```
  1301. // 0 <= `start_time` <= `soft_start_time` <= `end_time` and
  1302. // 0 <= `start_time` <= `soft_end_time` <= `end_time`.
  1303. // ```
  1304. message TimeWindow {
  1305. // The hard time window start time. If unspecified it will be set to
  1306. // `ShipmentModel.global_start_time`.
  1307. google.protobuf.Timestamp start_time = 1;
  1308. // The hard time window end time. If unspecified it will be set to
  1309. // `ShipmentModel.global_end_time`.
  1310. google.protobuf.Timestamp end_time = 2;
  1311. // The soft start time of the time window.
  1312. google.protobuf.Timestamp soft_start_time = 3;
  1313. // The soft end time of the time window.
  1314. google.protobuf.Timestamp soft_end_time = 4;
  1315. // A cost per hour added to other costs in the model if the event occurs
  1316. // before soft_start_time, computed as:
  1317. //
  1318. // ```
  1319. // max(0, soft_start_time - t.seconds)
  1320. // * cost_per_hour_before_soft_start_time / 3600,
  1321. // t being the time of the event.
  1322. // ```
  1323. //
  1324. // This cost must be positive, and the field can only be set if
  1325. // soft_start_time has been set.
  1326. optional double cost_per_hour_before_soft_start_time = 5;
  1327. // A cost per hour added to other costs in the model if the event occurs after
  1328. // `soft_end_time`, computed as:
  1329. //
  1330. // ```
  1331. // max(0, t.seconds - soft_end_time.seconds)
  1332. // * cost_per_hour_after_soft_end_time / 3600,
  1333. // t being the time of the event.
  1334. // ```
  1335. //
  1336. // This cost must be positive, and the field can only be set if
  1337. // `soft_end_time` has been set.
  1338. optional double cost_per_hour_after_soft_end_time = 6;
  1339. }
  1340. // Deprecated: Use [Shipment.Load][], [Vehicle.LoadLimit][] and
  1341. // [ShipmentRoute.VehicleLoad][] instead.
  1342. message CapacityQuantity {
  1343. option deprecated = true;
  1344. string type = 1;
  1345. int64 value = 2;
  1346. }
  1347. // Deprecated: Use [Vehicle.LoadLimit.Interval][] instead.
  1348. message CapacityQuantityInterval {
  1349. option deprecated = true;
  1350. string type = 1;
  1351. optional int64 min_value = 2;
  1352. optional int64 max_value = 3;
  1353. }
  1354. // A limit defining a maximum distance which can be traveled. It can be either
  1355. // hard or soft.
  1356. //
  1357. // If a soft limit is defined, both `soft_max_meters` and
  1358. // `cost_per_kilometer_above_soft_max` must be defined and be nonnegative.
  1359. message DistanceLimit {
  1360. // A hard limit constraining the distance to be at most max_meters. The limit
  1361. // must be nonnegative.
  1362. optional int64 max_meters = 1;
  1363. // A soft limit not enforcing a maximum distance limit, but when violated
  1364. // results in a cost which adds up to other costs defined in the model,
  1365. // with the same unit.
  1366. //
  1367. // If defined soft_max_meters must be less than max_meters and must be
  1368. // nonnegative.
  1369. optional int64 soft_max_meters = 2;
  1370. // Cost per kilometer incurred if `soft_max_meters` limit is violated. The
  1371. // additional cost is 0 if the distance is under the limit, otherwise the
  1372. // formula used to compute the cost is the following:
  1373. // ```
  1374. // (distance_meters - soft_max_meters) / 1000.0 *
  1375. // cost_per_kilometer_above_soft_max.
  1376. // ```
  1377. // The cost must be nonnegative.
  1378. optional double cost_per_kilometer_above_soft_max = 3;
  1379. }
  1380. // Specifies attributes of transitions between two consecutive visits on a
  1381. // route. Several `TransitionAttributes` may apply to the same transition: in
  1382. // that case, all extra costs add up and the strictest constraint or limit
  1383. // applies (following natural "AND" semantics).
  1384. message TransitionAttributes {
  1385. // Tags defining the set of (src->dst) transitions these attributes apply to.
  1386. //
  1387. // A source visit or vehicle start matches iff its
  1388. // [VisitRequest.tags][google.cloud.optimization.v1.Shipment.VisitRequest.tags]
  1389. // or [Vehicle.start_tags][google.cloud.optimization.v1.Vehicle.start_tags]
  1390. // either contains `src_tag` or does not contain `excluded_src_tag` (depending
  1391. // on which of these two fields is non-empty).
  1392. string src_tag = 1;
  1393. // See `src_tag`. Exactly one of `src_tag` and `excluded_src_tag` must be
  1394. // non-empty.
  1395. string excluded_src_tag = 2;
  1396. // A destination visit or vehicle end matches iff its
  1397. // [VisitRequest.tags][google.cloud.optimization.v1.Shipment.VisitRequest.tags]
  1398. // or [Vehicle.end_tags][google.cloud.optimization.v1.Vehicle.end_tags] either
  1399. // contains `dst_tag` or does not contain `excluded_dst_tag` (depending on
  1400. // which of these two fields is non-empty).
  1401. string dst_tag = 3;
  1402. // See `dst_tag`. Exactly one of `dst_tag` and `excluded_dst_tag` must be
  1403. // non-empty.
  1404. string excluded_dst_tag = 4;
  1405. // Specifies a cost for performing this transition. This is in the same unit
  1406. // as all other costs in the model and must not be negative. It is applied on
  1407. // top of all other existing costs.
  1408. double cost = 5;
  1409. // Specifies a cost per kilometer applied to the distance traveled while
  1410. // performing this transition. It adds up to any
  1411. // [Vehicle.cost_per_kilometer][google.cloud.optimization.v1.Vehicle.cost_per_kilometer]
  1412. // specified on vehicles.
  1413. double cost_per_kilometer = 6;
  1414. // Specifies a limit on the distance traveled while performing this
  1415. // transition.
  1416. //
  1417. // As of 2021/06, only soft limits are supported.
  1418. DistanceLimit distance_limit = 7;
  1419. // Specifies a delay incurred when performing this transition.
  1420. //
  1421. // This delay always occurs *after* finishing the source visit and *before*
  1422. // starting the destination visit.
  1423. google.protobuf.Duration delay = 8;
  1424. }
  1425. // Encapsulates a waypoint. Waypoints mark arrival and departure locations of
  1426. // VisitRequests, and start and end locations of Vehicles.
  1427. message Waypoint {
  1428. // Different ways to represent a location.
  1429. oneof location_type {
  1430. // A point specified using geographic coordinates, including an optional
  1431. // heading.
  1432. Location location = 1;
  1433. // The POI Place ID associated with the waypoint.
  1434. string place_id = 2;
  1435. }
  1436. // Indicates that the location of this waypoint is meant to have a preference
  1437. // for the vehicle to stop at a particular side of road. When you set this
  1438. // value, the route will pass through the location so that the vehicle can
  1439. // stop at the side of road that the location is biased towards from the
  1440. // center of the road. This option works only for the 'DRIVING' travel mode,
  1441. // and when the 'location_type' is set to 'location'.
  1442. bool side_of_road = 3;
  1443. }
  1444. // Encapsulates a location (a geographic point, and an optional heading).
  1445. message Location {
  1446. // The waypoint's geographic coordinates.
  1447. google.type.LatLng lat_lng = 1;
  1448. // The compass heading associated with the direction of the flow of traffic.
  1449. // This value is used to specify the side of the road to use for pickup and
  1450. // drop-off. Heading values can be from 0 to 360, where 0 specifies a heading
  1451. // of due North, 90 specifies a heading of due East, etc.
  1452. optional int32 heading = 2;
  1453. }
  1454. // Rules to generate time breaks for a vehicle (e.g. lunch breaks). A break
  1455. // is a contiguous period of time during which the vehicle remains idle at its
  1456. // current position and cannot perform any visit. A break may occur:
  1457. //
  1458. // * during the travel between two visits (which includes the time right
  1459. // before or right after a visit, but not in the middle of a visit), in
  1460. // which case it extends the corresponding transit time between the visits,
  1461. // * or before the vehicle start (the vehicle may not start in the middle of
  1462. // a break), in which case it does not affect the vehicle start time.
  1463. // * or after the vehicle end (ditto, with the vehicle end time).
  1464. message BreakRule {
  1465. // The sequence of breaks (i.e. their number and order) that apply to each
  1466. // vehicle must be known beforehand. The repeated `BreakRequest`s define
  1467. // that sequence, in the order in which they must occur. Their time windows
  1468. // (`earliest_start_time` / `latest_start_time`) may overlap, but they must
  1469. // be compatible with the order (this is checked).
  1470. message BreakRequest {
  1471. // Required. Lower bound (inclusive) on the start of the break.
  1472. google.protobuf.Timestamp earliest_start_time = 1
  1473. [(google.api.field_behavior) = REQUIRED];
  1474. // Required. Upper bound (inclusive) on the start of the break.
  1475. google.protobuf.Timestamp latest_start_time = 2
  1476. [(google.api.field_behavior) = REQUIRED];
  1477. // Required. Minimum duration of the break. Must be positive.
  1478. google.protobuf.Duration min_duration = 3
  1479. [(google.api.field_behavior) = REQUIRED];
  1480. }
  1481. // One may further constrain the frequency and duration of the breaks
  1482. // specified above, by enforcing a minimum break frequency, such as
  1483. // "There must be a break of at least 1 hour every 12 hours". Assuming that
  1484. // this can be interpreted as "Within any sliding time window of 12h, there
  1485. // must be at least one break of at least one hour", that example would
  1486. // translate to the following `FrequencyConstraint`:
  1487. // ```
  1488. // {
  1489. // min_break_duration { seconds: 3600 } # 1 hour.
  1490. // max_inter_break_duration { seconds: 39600 } # 11 hours (12 - 1 = 11).
  1491. // }
  1492. // ```
  1493. //
  1494. // The timing and duration of the breaks in the solution will respect all
  1495. // such constraints, in addition to the time windows and minimum durations
  1496. // already specified in the `BreakRequest`.
  1497. //
  1498. // A `FrequencyConstraint` may in practice apply to non-consecutive breaks.
  1499. // For example, the following schedule honors the "1h every 12h" example:
  1500. // ```
  1501. // 04:00 vehicle start
  1502. // .. performing travel and visits ..
  1503. // 09:00 1 hour break
  1504. // 10:00 end of the break
  1505. // .. performing travel and visits ..
  1506. // 12:00 20-min lunch break
  1507. // 12:20 end of the break
  1508. // .. performing travel and visits ..
  1509. // 21:00 1 hour break
  1510. // 22:00 end of the break
  1511. // .. performing travel and visits ..
  1512. // 23:59 vehicle end
  1513. // ```
  1514. message FrequencyConstraint {
  1515. // Required. Minimum break duration for this constraint. Nonnegative.
  1516. // See description of `FrequencyConstraint`.
  1517. google.protobuf.Duration min_break_duration = 1
  1518. [(google.api.field_behavior) = REQUIRED];
  1519. // Required. Maximum allowed span of any interval of time in the route that
  1520. // does not include at least partially a break of `duration >=
  1521. // min_break_duration`. Must be positive.
  1522. google.protobuf.Duration max_inter_break_duration = 2
  1523. [(google.api.field_behavior) = REQUIRED];
  1524. }
  1525. // Sequence of breaks. See the `BreakRequest` message.
  1526. repeated BreakRequest break_requests = 1;
  1527. // Several `FrequencyConstraint` may apply. They must all be satisfied by
  1528. // the `BreakRequest`s of this `BreakRule`. See `FrequencyConstraint`.
  1529. repeated FrequencyConstraint frequency_constraints = 2;
  1530. }
  1531. // A vehicle's route can be decomposed, along the time axis, like this (we
  1532. // assume there are n visits):
  1533. // ```
  1534. // | | | | | T[2], | | |
  1535. // | Transition | Visit #0 | | | V[2], | | |
  1536. // | #0 | aka | T[1] | V[1] | ... | V[n-1] | T[n] |
  1537. // | aka T[0] | V[0] | | | V[n-2],| | |
  1538. // | | | | | T[n-1] | | |
  1539. // ^ ^ ^ ^ ^ ^ ^ ^
  1540. // vehicle V[0].start V[0].end V[1]. V[1]. V[n]. V[n]. vehicle
  1541. // start (arrival) (departure) start end start end end
  1542. // ```
  1543. // Note that we make a difference between:
  1544. //
  1545. // * "punctual events", such as the vehicle start and end and each visit's start
  1546. // and end (aka arrival and departure). They happen at a given second.
  1547. // * "time intervals", such as the visits themselves, and the transition between
  1548. // visits. Though time intervals can sometimes have zero duration, i.e. start
  1549. // and end at the same second, they often have a positive duration.
  1550. //
  1551. // Invariants:
  1552. //
  1553. // * If there are n visits, there are n+1 transitions.
  1554. // * A visit is always surrounded by a transition before it (same index) and a
  1555. // transition after it (index + 1).
  1556. // * The vehicle start is always followed by transition #0.
  1557. // * The vehicle end is always preceded by transition #n.
  1558. //
  1559. // Zooming in, here is what happens during a `Transition` and a `Visit`:
  1560. // ```
  1561. // ---+-------------------------------------+-----------------------------+-->
  1562. // | TRANSITION[i] | VISIT[i] |
  1563. // | | |
  1564. // | * TRAVEL: the vehicle moves from | PERFORM the visit: |
  1565. // | VISIT[i-1].departure_location to | |
  1566. // | VISIT[i].arrival_location, which | * Spend some time: |
  1567. // | takes a given travel duration | the "visit duration". |
  1568. // | and distance | |
  1569. // | | * Load or unload |
  1570. // | * BREAKS: the driver may have | some quantities from the |
  1571. // | breaks (e.g. lunch break). | vehicle: the "demand". |
  1572. // | | |
  1573. // | * WAIT: the driver/vehicle does | |
  1574. // | nothing. This can happen for | |
  1575. // | many reasons, for example when | |
  1576. // | the vehicle reaches the next | |
  1577. // | event's destination before the | |
  1578. // | start of its time window | |
  1579. // | | |
  1580. // | * DELAY: *right before* the next | |
  1581. // | arrival. E.g. the vehicle and/or | |
  1582. // | driver spends time unloading. | |
  1583. // | | |
  1584. // ---+-------------------------------------+-----------------------------+-->
  1585. // ^ ^ ^
  1586. // V[i-1].end V[i].start V[i].end
  1587. // ```
  1588. // Lastly, here is how the TRAVEL, BREAKS, DELAY and WAIT can be arranged
  1589. // during a transition.
  1590. //
  1591. // * They don't overlap.
  1592. // * The DELAY is unique and *must* be a contiguous period of time right
  1593. // before the next visit (or vehicle end). Thus, it suffice to know the
  1594. // delay duration to know its start and end time.
  1595. // * The BREAKS are contiguous, non-overlapping periods of time. The
  1596. // response specifies the start time and duration of each break.
  1597. // * TRAVEL and WAIT are "preemptable": they can be interrupted several times
  1598. // during this transition. Clients can assume that travel happens "as soon as
  1599. // possible" and that "wait" fills the remaining time.
  1600. //
  1601. // A (complex) example:
  1602. // ```
  1603. // TRANSITION[i]
  1604. // --++-----+-----------------------------------------------------------++-->
  1605. // || | | | | | | ||
  1606. // || T | B | T | | B | | D ||
  1607. // || r | r | r | W | r | W | e ||
  1608. // || a | e | a | a | e | a | l ||
  1609. // || v | a | v | i | a | i | a ||
  1610. // || e | k | e | t | k | t | y ||
  1611. // || l | | l | | | | ||
  1612. // || | | | | | | ||
  1613. // --++-----------------------------------------------------------------++-->
  1614. // ```
  1615. message ShipmentRoute {
  1616. // Deprecated: Use [ShipmentRoute.Transition.delay_duration][] instead.
  1617. // Time interval spent on the route resulting from a
  1618. // [TransitionAttributes.delay][google.cloud.optimization.v1.TransitionAttributes.delay].
  1619. message Delay {
  1620. option deprecated = true;
  1621. // Start of the delay.
  1622. google.protobuf.Timestamp start_time = 1;
  1623. // Duration of the delay.
  1624. google.protobuf.Duration duration = 2;
  1625. }
  1626. // A visit performed during a route. This visit corresponds to a pickup or a
  1627. // delivery of a `Shipment`.
  1628. message Visit {
  1629. // Index of the `shipments` field in the source
  1630. // [ShipmentModel][google.cloud.optimization.v1.ShipmentModel].
  1631. int32 shipment_index = 1;
  1632. // If true the visit corresponds to a pickup of a `Shipment`. Otherwise, it
  1633. // corresponds to a delivery.
  1634. bool is_pickup = 2;
  1635. // Index of `VisitRequest` in either the pickup or delivery field of the
  1636. // `Shipment` (see `is_pickup`).
  1637. int32 visit_request_index = 3;
  1638. // Time at which the visit starts. Note that the vehicle may arrive earlier
  1639. // than this at the visit location. Times are consistent with the
  1640. // `ShipmentModel`.
  1641. google.protobuf.Timestamp start_time = 4;
  1642. // Total visit load demand as the sum of the shipment and the visit request
  1643. // `load_demands`. The values are negative if the visit is a delivery.
  1644. // Demands are reported for the same types as the
  1645. // [Transition.loads][google.cloud.optimization.v1.ShipmentRoute.Transition]
  1646. // (see this field).
  1647. map<string, Shipment.Load> load_demands = 11;
  1648. // Extra detour time due to the shipments visited on the route before the
  1649. // visit and to the potential waiting time induced by time windows.
  1650. // If the visit is a delivery, the detour is computed from the corresponding
  1651. // pickup visit and is equal to:
  1652. // ```
  1653. // start_time(delivery) - start_time(pickup)
  1654. // - (duration(pickup) + travel duration from the pickup location
  1655. // to the delivery location).
  1656. // ```
  1657. // Otherwise, it is computed from the vehicle `start_location` and is equal
  1658. // to:
  1659. // ```
  1660. // start_time - vehicle_start_time - travel duration from
  1661. // the vehicle's `start_location` to the visit.
  1662. // ```
  1663. google.protobuf.Duration detour = 6;
  1664. // Copy of the corresponding `Shipment.label`, if specified in the
  1665. // `Shipment`.
  1666. string shipment_label = 7;
  1667. // Copy of the corresponding
  1668. // [VisitRequest.label][google.cloud.optimization.v1.Shipment.VisitRequest.label],
  1669. // if specified in the `VisitRequest`.
  1670. string visit_label = 8;
  1671. // Deprecated: Use [ShipmentRoute.Transition.loads][] instead.
  1672. // Vehicle loads upon arrival at the visit location, for each
  1673. // type specified in
  1674. // [Vehicle.capacities][google.cloud.optimization.v1.Vehicle.capacities],
  1675. // `start_load_intervals`, `end_load_intervals` or `demands`.
  1676. //
  1677. // Exception: we omit loads for quantity types unconstrained by intervals
  1678. // and that don't have any non-zero demand on the route.
  1679. repeated CapacityQuantity arrival_loads = 9 [deprecated = true];
  1680. // Deprecated: Use [ShipmentRoute.Transition.delay_duration][] instead.
  1681. Delay delay_before_start = 10 [deprecated = true];
  1682. // Deprecated: Use [Visit.load_demands][] instead.
  1683. repeated CapacityQuantity demands = 5 [deprecated = true];
  1684. }
  1685. // Transition between two events on the route. See the description of
  1686. // [ShipmentRoute][google.cloud.optimization.v1.ShipmentRoute].
  1687. //
  1688. // If the vehicle does not have a `start_location` and/or `end_location`, the
  1689. // corresponding travel metrics are 0.
  1690. message Transition {
  1691. // Travel duration during this transition.
  1692. google.protobuf.Duration travel_duration = 1;
  1693. // Distance traveled during the transition.
  1694. double travel_distance_meters = 2;
  1695. // When traffic is requested via
  1696. // [OptimizeToursRequest.consider_road_traffic]
  1697. // [google.cloud.optimization.v1.OptimizeToursRequest.consider_road_traffic],
  1698. // and the traffic info couldn't be retrieved for a `Transition`, this
  1699. // boolean is set to true. This may be temporary (rare hiccup in the
  1700. // realtime traffic servers) or permanent (no data for this location).
  1701. bool traffic_info_unavailable = 3;
  1702. // Sum of the delay durations applied to this transition. If any, the delay
  1703. // starts exactly `delay_duration` seconds before the next event (visit or
  1704. // vehicle end). See
  1705. // [TransitionAttributes.delay][google.cloud.optimization.v1.TransitionAttributes.delay].
  1706. google.protobuf.Duration delay_duration = 4;
  1707. // Sum of the duration of the breaks occurring during this transition, if
  1708. // any. Details about each break's start time and duration are stored in
  1709. // [ShipmentRoute.breaks][google.cloud.optimization.v1.ShipmentRoute.breaks].
  1710. google.protobuf.Duration break_duration = 5;
  1711. // Time spent waiting during this transition. Wait duration corresponds to
  1712. // idle time and does not include break time. Also note that this wait time
  1713. // may be split into several non-contiguous intervals.
  1714. google.protobuf.Duration wait_duration = 6;
  1715. // Total duration of the transition, provided for convenience. It is equal
  1716. // to:
  1717. //
  1718. // * next visit `start_time` (or `vehicle_end_time` if this is the last
  1719. // transition) - this transition's `start_time`;
  1720. // * if `ShipmentRoute.has_traffic_infeasibilities` is false, the following
  1721. // additionally holds: `total_duration = travel_duration + delay_duration
  1722. // + break_duration + wait_duration`.
  1723. google.protobuf.Duration total_duration = 7;
  1724. // Start time of this transition.
  1725. google.protobuf.Timestamp start_time = 8;
  1726. // The encoded polyline representation of the route followed during the
  1727. // transition.
  1728. // This field is only populated if [populate_transition_polylines]
  1729. // [google.cloud.optimization.v1.OptimizeToursRequest.populate_transition_polylines]
  1730. // is set to true.
  1731. EncodedPolyline route_polyline = 9;
  1732. // Vehicle loads during this transition, for each type that either appears
  1733. // in this vehicle's
  1734. // [Vehicle.load_limits][google.cloud.optimization.v1.Vehicle.load_limits],
  1735. // or that have non-zero
  1736. // [Shipment.load_demands][google.cloud.optimization.v1.Shipment.load_demands]
  1737. // on some shipment performed on this route.
  1738. //
  1739. // The loads during the first transition are the starting loads of the
  1740. // vehicle route. Then, after each visit, the visit's `load_demands` are
  1741. // either added or subtracted to get the next transition's loads, depending
  1742. // on whether the visit was a pickup or a delivery.
  1743. map<string, VehicleLoad> vehicle_loads = 11;
  1744. // Deprecated: Use [Transition.vehicle_loads][] instead.
  1745. repeated CapacityQuantity loads = 10 [deprecated = true];
  1746. }
  1747. // Reports the actual load of the vehicle at some point along the route,
  1748. // for a given type (see
  1749. // [Transition.vehicle_loads][google.cloud.optimization.v1.ShipmentRoute.Transition.vehicle_loads]).
  1750. message VehicleLoad {
  1751. // The amount of load on the vehicle, for the given type. The unit of load
  1752. // is usually indicated by the type. See
  1753. // [Transition.vehicle_loads][google.cloud.optimization.v1.ShipmentRoute.Transition.vehicle_loads].
  1754. int64 amount = 1;
  1755. }
  1756. // The encoded representation of a polyline. More information on polyline
  1757. // encoding can be found here:
  1758. // https://developers.google.com/maps/documentation/utilities/polylinealgorithm
  1759. // https://developers.google.com/maps/documentation/javascript/reference/geometry#encoding.
  1760. message EncodedPolyline {
  1761. // String representing encoded points of the polyline.
  1762. string points = 1;
  1763. }
  1764. // Data representing the execution of a break.
  1765. message Break {
  1766. // Start time of a break.
  1767. google.protobuf.Timestamp start_time = 1;
  1768. // Duration of a break.
  1769. google.protobuf.Duration duration = 2;
  1770. }
  1771. // Deprecated: Use [ShipmentRoute.transitions][] instead.
  1772. // Travel between each visit, along the route: from the
  1773. // vehicle's `start_location` to the first visit's `arrival_location`, then
  1774. // from the first visit's `departure_location` to the second visit's
  1775. // `arrival_location`, and so on until the vehicle's `end_location`. This
  1776. // accounts only for the actual travel between visits, not counting the
  1777. // waiting time, the time spent performing a visit, nor the distance covered
  1778. // during a visit.
  1779. //
  1780. // Invariant: `travel_steps_size() == visits_size() + 1`.
  1781. //
  1782. // If the vehicle does not have a start_ and/or end_location, the
  1783. // corresponding travel metrics are 0 and/or empty.
  1784. message TravelStep {
  1785. option deprecated = true;
  1786. // Duration of the travel step.
  1787. google.protobuf.Duration duration = 1;
  1788. // Distance traveled during the step.
  1789. double distance_meters = 2;
  1790. // When traffic is requested via
  1791. // [OptimizeToursRequest.consider_road_traffic][google.cloud.optimization.v1.OptimizeToursRequest.consider_road_traffic],
  1792. // and the traffic info couldn't be retrieved for a TravelStep, this boolean
  1793. // is set to true. This may be temporary (rare hiccup in the realtime
  1794. // traffic servers) or permanent (no data for this location).
  1795. bool traffic_info_unavailable = 3;
  1796. // The encoded polyline representation of the route followed during the
  1797. // step.
  1798. //
  1799. // This field is only populated if
  1800. // [OptimizeToursRequest.populate_travel_step_polylines][google.cloud.optimization.v1.OptimizeToursRequest.populate_travel_step_polylines]
  1801. // is set to true.
  1802. EncodedPolyline route_polyline = 4;
  1803. }
  1804. // Vehicle performing the route, identified by its index in the source
  1805. // `ShipmentModel`.
  1806. int32 vehicle_index = 1;
  1807. // Label of the vehicle performing this route, equal to
  1808. // `ShipmentModel.vehicles(vehicle_index).label`, if specified.
  1809. string vehicle_label = 2;
  1810. // Time at which the vehicle starts its route.
  1811. google.protobuf.Timestamp vehicle_start_time = 5;
  1812. // Time at which the vehicle finishes its route.
  1813. google.protobuf.Timestamp vehicle_end_time = 6;
  1814. // Ordered sequence of visits representing a route.
  1815. // visits[i] is the i-th visit in the route.
  1816. // If this field is empty, the vehicle is considered as unused.
  1817. repeated Visit visits = 7;
  1818. // Ordered list of transitions for the route.
  1819. repeated Transition transitions = 8;
  1820. // When
  1821. // [OptimizeToursRequest.consider_road_traffic][google.cloud.optimization.v1.OptimizeToursRequest.consider_road_traffic],
  1822. // is set to true, this field indicates that inconsistencies in route timings
  1823. // are predicted using traffic-based travel duration estimates. There may be
  1824. // insufficient time to complete traffic-adjusted travel, delays, and breaks
  1825. // between visits, before the first visit, or after the last visit, while
  1826. // still satisfying the visit and vehicle time windows. For example,
  1827. //
  1828. // ```
  1829. // start_time(previous_visit) + duration(previous_visit) +
  1830. // travel_duration(previous_visit, next_visit) > start_time(next_visit)
  1831. // ```
  1832. //
  1833. // Arrival at next_visit will likely happen later than its current
  1834. // time window due the increased estimate of travel time
  1835. // `travel_duration(previous_visit, next_visit)` due to traffic. Also, a break
  1836. // may be forced to overlap with a visit due to an increase in travel time
  1837. // estimates and visit or break time window restrictions.
  1838. bool has_traffic_infeasibilities = 9;
  1839. // The encoded polyline representation of the route.
  1840. // This field is only populated if
  1841. // [OptimizeToursRequest.populate_polylines][google.cloud.optimization.v1.OptimizeToursRequest.populate_polylines]
  1842. // is set to true.
  1843. EncodedPolyline route_polyline = 10;
  1844. // Breaks scheduled for the vehicle performing this route.
  1845. // The `breaks` sequence represents time intervals, each starting at the
  1846. // corresponding `start_time` and lasting `duration` seconds.
  1847. repeated Break breaks = 11;
  1848. // Duration, distance and load metrics for this route. The fields of
  1849. // [AggregatedMetrics][google.cloud.optimization.v1.AggregatedMetrics] are
  1850. // summed over all
  1851. // [ShipmentRoute.transitions][google.cloud.optimization.v1.ShipmentRoute.transitions]
  1852. // or
  1853. // [ShipmentRoute.visits][google.cloud.optimization.v1.ShipmentRoute.visits],
  1854. // depending on the context.
  1855. AggregatedMetrics metrics = 12;
  1856. // Cost of the route, broken down by cost-related request fields.
  1857. // The keys are proto paths, relative to the input OptimizeToursRequest, e.g.
  1858. // "model.shipments.pickups.cost", and the values are the total cost
  1859. // generated by the corresponding cost field, aggregated over the whole route.
  1860. // In other words, costs["model.shipments.pickups.cost"] is the sum of all
  1861. // pickup costs over the route. All costs defined in the model are reported in
  1862. // detail here with the exception of costs related to TransitionAttributes
  1863. // that are only reported in an aggregated way as of 2022/01.
  1864. map<string, double> route_costs = 17;
  1865. // Total cost of the route. The sum of all costs in the cost map.
  1866. double route_total_cost = 18;
  1867. // Deprecated: Use [ShipmentRoute.Transition.loads][] instead.
  1868. // Vehicle loads upon arrival at its end location, for each
  1869. // type specified in
  1870. // [Vehicle.capacities][google.cloud.optimization.v1.Vehicle.capacities],
  1871. // `start_load_intervals`, `end_load_intervals` or demands. Exception: we omit
  1872. // loads for quantity types unconstrained by intervals and that don't have any
  1873. // non-zero demand on the route.
  1874. repeated CapacityQuantity end_loads = 13 [deprecated = true];
  1875. // Deprecated: Use [ShipmentRoute.Transition][] instead.
  1876. // Ordered list of travel steps for the route.
  1877. repeated TravelStep travel_steps = 14 [deprecated = true];
  1878. // Deprecated: No longer used.
  1879. // This field will only be populated at the
  1880. // [ShipmentRoute.Visit][google.cloud.optimization.v1.ShipmentRoute.Visit]
  1881. // level. Extra detour time due to the shipments visited on the route.
  1882. //
  1883. // It is equal to `vehicle_end_time` - `vehicle_start_time` - travel duration
  1884. // from the vehicle's start_location to its `end_location`.
  1885. google.protobuf.Duration vehicle_detour = 15 [deprecated = true];
  1886. // Deprecated: Use [ShipmentRoute.Transition.delay_duration][] instead.
  1887. // Delay occurring before the vehicle end. See
  1888. // [TransitionAttributes.delay][google.cloud.optimization.v1.TransitionAttributes.delay].
  1889. Delay delay_before_vehicle_end = 16 [deprecated = true];
  1890. }
  1891. // Specifies details of unperformed shipments in a solution. For trivial cases
  1892. // and/or if we are able to identify the cause for skipping, we report the
  1893. // reason here.
  1894. message SkippedShipment {
  1895. // If we can explain why the shipment was skipped, reasons will be listed
  1896. // here. If the reason is not the same for all vehicles, `reason` will have
  1897. // more than 1 element. A skipped shipment cannot have duplicate reasons,
  1898. // i.e. where all fields are the same except for `example_vehicle_index`.
  1899. // Example:
  1900. // ```
  1901. // reasons {
  1902. // code: DEMAND_EXCEEDS_VEHICLE_CAPACITY
  1903. // example_vehicle_index: 1
  1904. // example_exceeded_capacity_type: "Apples"
  1905. // }
  1906. // reasons {
  1907. // code: DEMAND_EXCEEDS_VEHICLE_CAPACITY
  1908. // example_vehicle_index: 3
  1909. // example_exceeded_capacity_type: "Pears"
  1910. // }
  1911. // reasons {
  1912. // code: CANNOT_BE_PERFORMED_WITHIN_VEHICLE_DISTANCE_LIMIT
  1913. // example_vehicle_index: 1
  1914. // }
  1915. // ```
  1916. // The skipped shipment is incompatible with all vehicles. The reasons may
  1917. // be different for all vehicles but at least one vehicle's "Apples"
  1918. // capacity would be exceeded (including vehicle 1), at least one vehicle's
  1919. // "Pears" capacity would be exceeded (including vehicle 3) and at least one
  1920. // vehicle's distance limit would be exceeded (including vehicle 1).
  1921. message Reason {
  1922. // Code identifying the reason type. The order here is meaningless. In
  1923. // particular, it gives no indication of whether a given reason will
  1924. // appear before another in the solution, if both apply.
  1925. enum Code {
  1926. // This should never be used. If we are unable to understand why a
  1927. // shipment was skipped, we simply return an empty set of reasons.
  1928. CODE_UNSPECIFIED = 0;
  1929. // There is no vehicle in the model making all shipments infeasible.
  1930. NO_VEHICLE = 1;
  1931. // The demand of the shipment exceeds a vehicle's capacity for some
  1932. // capacity types, one of which is `example_exceeded_capacity_type`.
  1933. DEMAND_EXCEEDS_VEHICLE_CAPACITY = 2;
  1934. // The minimum distance necessary to perform this shipment, i.e. from
  1935. // the vehicle's `start_location` to the shipment's pickup and/or delivery
  1936. // locations and to the vehicle's end location exceeds the vehicle's
  1937. // `route_distance_limit`.
  1938. //
  1939. // Note that for this computation we use the geodesic distances.
  1940. CANNOT_BE_PERFORMED_WITHIN_VEHICLE_DISTANCE_LIMIT = 3;
  1941. // The minimum time necessary to perform this shipment, including travel
  1942. // time, wait time and service time exceeds the vehicle's
  1943. // `route_duration_limit`.
  1944. //
  1945. // Note: travel time is computed in the best-case scenario, namely as
  1946. // geodesic distance x 36 m/s (roughly 130 km/hour).
  1947. CANNOT_BE_PERFORMED_WITHIN_VEHICLE_DURATION_LIMIT = 4;
  1948. // Same as above but we only compare minimum travel time and the
  1949. // vehicle's `travel_duration_limit`.
  1950. CANNOT_BE_PERFORMED_WITHIN_VEHICLE_TRAVEL_DURATION_LIMIT = 5;
  1951. // The vehicle cannot perform this shipment in the best-case scenario
  1952. // (see `CANNOT_BE_PERFORMED_WITHIN_VEHICLE_DURATION_LIMIT` for time
  1953. // computation) if it starts at its earliest start time: the total time
  1954. // would make the vehicle end after its latest end time.
  1955. CANNOT_BE_PERFORMED_WITHIN_VEHICLE_TIME_WINDOWS = 6;
  1956. // The `allowed_vehicle_indices` field of the shipment is not empty and
  1957. // this vehicle does not belong to it.
  1958. VEHICLE_NOT_ALLOWED = 7;
  1959. }
  1960. // Refer to the comments of Code.
  1961. Code code = 1;
  1962. // If the reason is related to a shipment-vehicle incompatibility, this
  1963. // field provides the index of one relevant vehicle.
  1964. optional int32 example_vehicle_index = 2;
  1965. // If the reason code is `DEMAND_EXCEEDS_VEHICLE_CAPACITY`, documents one
  1966. // capacity type that is exceeded.
  1967. string example_exceeded_capacity_type = 3;
  1968. }
  1969. // The index corresponds to the index of the shipment in the source
  1970. // `ShipmentModel`.
  1971. int32 index = 1;
  1972. // Copy of the corresponding
  1973. // [Shipment.label][google.cloud.optimization.v1.Shipment.label], if specified
  1974. // in the `Shipment`.
  1975. string label = 2;
  1976. // A list of reasons that explain why the shipment was skipped. See comment
  1977. // above `Reason`.
  1978. repeated Reason reasons = 3;
  1979. }
  1980. // Aggregated metrics for
  1981. // [ShipmentRoute][google.cloud.optimization.v1.ShipmentRoute] (resp. for
  1982. // [OptimizeToursResponse][google.cloud.optimization.v1.OptimizeToursResponse]
  1983. // over all [Transition][google.cloud.optimization.v1.ShipmentRoute.Transition]
  1984. // and/or [Visit][google.cloud.optimization.v1.ShipmentRoute.Visit] (resp. over
  1985. // all [ShipmentRoute][google.cloud.optimization.v1.ShipmentRoute]) elements.
  1986. message AggregatedMetrics {
  1987. // Number of shipments performed. Note that a pickup and delivery pair only
  1988. // counts once.
  1989. int32 performed_shipment_count = 1;
  1990. // Total travel duration for a route or a solution.
  1991. google.protobuf.Duration travel_duration = 2;
  1992. // Total wait duration for a route or a solution.
  1993. google.protobuf.Duration wait_duration = 3;
  1994. // Total delay duration for a route or a solution.
  1995. google.protobuf.Duration delay_duration = 4;
  1996. // Total break duration for a route or a solution.
  1997. google.protobuf.Duration break_duration = 5;
  1998. // Total visit duration for a route or a solution.
  1999. google.protobuf.Duration visit_duration = 6;
  2000. // The total duration should be equal to the sum of all durations above.
  2001. // For routes, it also corresponds to
  2002. // [ShipmentRoute.vehicle_end_time][google.cloud.optimization.v1.ShipmentRoute.vehicle_end_time]
  2003. // -
  2004. // [ShipmentRoute.vehicle_start_time][google.cloud.optimization.v1.ShipmentRoute.vehicle_start_time].
  2005. google.protobuf.Duration total_duration = 7;
  2006. // Total travel distance for a route or a solution.
  2007. double travel_distance_meters = 8;
  2008. // Maximum load achieved over the entire route (resp. solution), for each of
  2009. // the quantities on this route (resp. solution), computed as the maximum over
  2010. // all
  2011. // [Transition.vehicle_loads][google.cloud.optimization.v1.ShipmentRoute.Transition.vehicle_loads]
  2012. // (resp.
  2013. // [ShipmentRoute.metrics.max_loads][google.cloud.optimization.v1.AggregatedMetrics.max_loads].
  2014. map<string, ShipmentRoute.VehicleLoad> max_loads = 9;
  2015. // Deprecated: Use [ShipmentRoute.route_costs][] and
  2016. // [OptimizeToursResponse.Metrics.costs][] instead.
  2017. map<string, double> costs = 10 [deprecated = true];
  2018. // Deprecated: Use [ShipmentRoute.route_total_cost][] and
  2019. // [OptimizeToursResponse.Metrics.total_cost][] instead.
  2020. double total_cost = 11 [deprecated = true];
  2021. }
  2022. // Solution injected in the request including information about which visits
  2023. // must be constrained and how they must be constrained.
  2024. message InjectedSolutionConstraint {
  2025. // For a group of vehicles, specifies at what threshold(s) constraints on
  2026. // visits will be relaxed and to which level. Shipments listed in
  2027. // the `skipped_shipment` field are constrained to be skipped; i.e., they
  2028. // cannot be performed.
  2029. message ConstraintRelaxation {
  2030. // If `relaxations` is empty, the start time and sequence of all visits
  2031. // on `routes` are fully constrained and no new visits may be inserted or
  2032. // added to those routes. Also, a vehicle's start and end time in
  2033. // `routes` is fully constrained, unless the vehicle is empty (i.e., has no
  2034. // visits and has `used_if_route_is_empty` set to false in the model).
  2035. //
  2036. // `relaxations(i).level` specifies the constraint relaxation level applied
  2037. // to a visit #j that satisfies:
  2038. //
  2039. // * `route.visits(j).start_time >= relaxations(i).threshold_time` AND
  2040. // * `j + 1 >= relaxations(i).threshold_visit_count`
  2041. //
  2042. // Similarly, the vehicle start is relaxed to `relaxations(i).level` if it
  2043. // satisfies:
  2044. //
  2045. // * `vehicle_start_time >= relaxations(i).threshold_time` AND
  2046. // * `relaxations(i).threshold_visit_count == 0`
  2047. // and the vehicle end is relaxed to `relaxations(i).level` if it satisfies:
  2048. // * `vehicle_end_time >= relaxations(i).threshold_time` AND
  2049. // * `route.visits_size() + 1 >= relaxations(i).threshold_visit_count`
  2050. //
  2051. // To apply a relaxation level if a visit meets the `threshold_visit_count`
  2052. // OR the `threshold_time` add two `relaxations` with the same `level`:
  2053. // one with only `threshold_visit_count` set and the other with only
  2054. // `threshold_time` set. If a visit satisfies the conditions of multiple
  2055. // `relaxations`, the most relaxed level applies. As a result, from the
  2056. // vehicle start through the route visits in order to the vehicle end, the
  2057. // relaxation level becomes more relaxed: i.e., the relaxation level is
  2058. // non-decreasing as the route progresses.
  2059. //
  2060. // The timing and sequence of route visits that do not satisfy the
  2061. // threshold conditions of any `relaxations` are fully constrained
  2062. // and no visits may be inserted into these sequences. Also, if a
  2063. // vehicle start or end does not satisfy the conditions of any
  2064. // relaxation the time is fixed, unless the vehicle is empty.
  2065. message Relaxation {
  2066. // Expresses the different constraint relaxation levels, which are
  2067. // applied for a visit and those that follow when it satifies the
  2068. // threshold conditions.
  2069. //
  2070. // The enumeration below is in order of increasing relaxation.
  2071. enum Level {
  2072. // Implicit default relaxation level: no constraints are relaxed,
  2073. // i.e., all visits are fully constrained.
  2074. //
  2075. // This value must not be explicly used in `level`.
  2076. LEVEL_UNSPECIFIED = 0;
  2077. // Visit start times and vehicle start/end times will be relaxed, but
  2078. // each visit remains bound to the same vehicle and the visit sequence
  2079. // must be observed: no visit can be inserted between them or before
  2080. // them.
  2081. RELAX_VISIT_TIMES_AFTER_THRESHOLD = 1;
  2082. // Same as `RELAX_VISIT_TIMES_AFTER_THRESHOLD`, but the visit sequence
  2083. // is also relaxed: visits remain simply bound to their vehicle.
  2084. RELAX_VISIT_TIMES_AND_SEQUENCE_AFTER_THRESHOLD = 2;
  2085. // Same as `RELAX_VISIT_TIMES_AND_SEQUENCE_AFTER_THRESHOLD`, but the
  2086. // vehicle is also relaxed: visits are completely free at or after the
  2087. // threshold time and can potentially become unperformed.
  2088. RELAX_ALL_AFTER_THRESHOLD = 3;
  2089. }
  2090. // The constraint relaxation level that applies when the conditions
  2091. // at or after `threshold_time` AND at least `threshold_visit_count` are
  2092. // satified.
  2093. Level level = 1;
  2094. // The time at or after which the relaxation `level` may be applied.
  2095. google.protobuf.Timestamp threshold_time = 2;
  2096. // The number of visits at or after which the relaxation `level` may be
  2097. // applied. If `threshold_visit_count` is 0 (or unset), the `level` may be
  2098. // applied directly at the vehicle start.
  2099. //
  2100. // If it is `route.visits_size() + 1`, the `level` may only be applied to
  2101. // the vehicle end. If it is more than `route.visits_size() + 1`,
  2102. // `level` is not applied at all for that route.
  2103. int32 threshold_visit_count = 3;
  2104. }
  2105. // All the visit constraint relaxations that will apply to visits on
  2106. // routes with vehicles in `vehicle_indices`.
  2107. repeated Relaxation relaxations = 1;
  2108. // Specifies the vehicle indices to which the visit constraint
  2109. // `relaxations` apply. If empty, this is considered the default and the
  2110. // `relaxations` apply to all vehicles that are not specified in other
  2111. // `constraint_relaxations`. There can be at most one default, i.e., at
  2112. // most one constraint relaxation field is allowed empty
  2113. // `vehicle_indices`. A vehicle index can only be listed once, even within
  2114. // several `constraint_relaxations`.
  2115. //
  2116. // A vehicle index is mapped the same as
  2117. // [ShipmentRoute.vehicle_index][google.cloud.optimization.v1.ShipmentRoute.vehicle_index],
  2118. // if `interpret_injected_solutions_using_labels` is true (see `fields`
  2119. // comment).
  2120. repeated int32 vehicle_indices = 2;
  2121. }
  2122. // Routes of the solution to inject. Some routes may be omitted from the
  2123. // original solution. The routes and skipped shipments must satisfy the basic
  2124. // validity assumptions listed for `injected_first_solution_routes`.
  2125. repeated ShipmentRoute routes = 1;
  2126. // Skipped shipments of the solution to inject. Some may be omitted from the
  2127. // original solution. See the `routes` field.
  2128. repeated SkippedShipment skipped_shipments = 2;
  2129. // For zero or more groups of vehicles, specifies when and how much to relax
  2130. // constraints. If this field is empty, all non-empty vehicle routes are
  2131. // fully constrained.
  2132. repeated ConstraintRelaxation constraint_relaxations = 3;
  2133. }
  2134. // Describes an error encountered when validating an `OptimizeToursRequest`.
  2135. message OptimizeToursValidationError {
  2136. // Specifies a context for the validation error. A `FieldReference` always
  2137. // refers to a given field in this file and follows the same hierarchical
  2138. // structure. For example, we may specify element #2 of `start_time_windows`
  2139. // of vehicle #5 using:
  2140. // ```
  2141. // name: "vehicles" index: 5 sub_field { name: "end_time_windows" index: 2 }
  2142. // ```
  2143. // We however omit top-level entities such as `OptimizeToursRequest` or
  2144. // `ShipmentModel` to avoid crowding the message.
  2145. message FieldReference {
  2146. // Name of the field, e.g., "vehicles".
  2147. string name = 1;
  2148. oneof index_or_key {
  2149. // Index of the field if repeated.
  2150. int32 index = 2;
  2151. // Key if the field is a map.
  2152. string key = 4;
  2153. }
  2154. // Recursively nested sub-field, if needed.
  2155. FieldReference sub_field = 3;
  2156. }
  2157. // A validation error is defined by the pair (`code`, `display_name`) which
  2158. // are always present.
  2159. //
  2160. // Other fields (below) provide more context about the error.
  2161. //
  2162. // *MULTIPLE ERRORS*:
  2163. // When there are multiple errors, the validation process tries to output
  2164. // several of them. Much like a compiler, this is an imperfect process. Some
  2165. // validation errors will be "fatal", meaning that they stop the entire
  2166. // validation process. This is the case for `display_name="UNSPECIFIED"`
  2167. // errors, among others. Some may cause the validation process to skip other
  2168. // errors.
  2169. //
  2170. // *STABILITY*:
  2171. // `code` and `display_name` should be very stable. But new codes and
  2172. // display names may appear over time, which may cause a given (invalid)
  2173. // request to yield a different (`code`, `display_name`) pair because the new
  2174. // error hid the old one (see "MULTIPLE ERRORS").
  2175. //
  2176. // *REFERENCE*: A list of all (code, name) pairs:
  2177. //
  2178. // * UNSPECIFIED = 0;
  2179. // * VALIDATION_TIMEOUT_ERROR = 10; Validation couldn't be completed within
  2180. // the deadline.
  2181. //
  2182. // * REQUEST_OPTIONS_ERROR = 12;
  2183. // * REQUEST_OPTIONS_INVALID_SOLVING_MODE = 1201;
  2184. // * REQUEST_OPTIONS_INVALID_MAX_VALIDATION_ERRORS = 1203;
  2185. // * REQUEST_OPTIONS_INVALID_GEODESIC_METERS_PER_SECOND = 1204;
  2186. // * REQUEST_OPTIONS_GEODESIC_METERS_PER_SECOND_TOO_SMALL = 1205;
  2187. // * REQUEST_OPTIONS_MISSING_GEODESIC_METERS_PER_SECOND = 1206;
  2188. // * REQUEST_OPTIONS_POPULATE_PATHFINDER_TRIPS_AND_GEODESIC_DISTANCE
  2189. // = 1207;
  2190. // * REQUEST_OPTIONS_COST_MODEL_OPTIONS_AND_GEODESIC_DISTANCE = 1208;
  2191. // * REQUEST_OPTIONS_TRAVEL_MODE_INCOMPATIBLE_WITH_TRAFFIC = 1211;
  2192. // * REQUEST_OPTIONS_MULTIPLE_TRAFFIC_FLAVORS = 1212;
  2193. // * REQUEST_OPTIONS_INVALID_TRAFFIC_FLAVOR = 1213;
  2194. // * REQUEST_OPTIONS_TRAFFIC_ENABLED_WITHOUT_GLOBAL_START_TIME = 1214;
  2195. // * REQUEST_OPTIONS_TRAFFIC_ENABLED_WITH_PRECEDENCES = 1215;
  2196. // * REQUEST_OPTIONS_TRAFFIC_PREFILL_MODE_INVALID = 1216;
  2197. // * REQUEST_OPTIONS_TRAFFIC_PREFILL_ENABLED_WITHOUT_TRAFFIC = 1217;
  2198. // * INJECTED_SOLUTION_ERROR = 20;
  2199. // * INJECTED_SOLUTION_MISSING_LABEL = 2000;
  2200. // * INJECTED_SOLUTION_DUPLICATE_LABEL = 2001;
  2201. // * INJECTED_SOLUTION_AMBIGUOUS_INDEX = 2002;
  2202. // * SHIPMENT_MODEL_ERROR = 22;
  2203. // * SHIPMENT_MODEL_TOO_LARGE = 2200;
  2204. // * SHIPMENT_MODEL_TOO_MANY_CAPACITY_TYPES = 2201;
  2205. // * SHIPMENT_MODEL_GLOBAL_START_TIME_NEGATIVE_OR_NAN = 2202;
  2206. // * SHIPMENT_MODEL_GLOBAL_END_TIME_TOO_LARGE_OR_NAN = 2203;
  2207. // * SHIPMENT_MODEL_GLOBAL_START_TIME_AFTER_GLOBAL_END_TIME = 2204;
  2208. // * SHIPMENT_MODEL_GLOBAL_DURATION_TOO_LONG = 2205;
  2209. // * INDEX_ERROR = 24;
  2210. // * TAG_ERROR = 26;
  2211. // * TIME_WINDOW_ERROR = 28;
  2212. // * TIME_WINDOW_INVALID_START_TIME = 2800;
  2213. // * TIME_WINDOW_INVALID_END_TIME = 2801;
  2214. // * TIME_WINDOW_INVALID_SOFT_START_TIME = 2802;
  2215. // * TIME_WINDOW_INVALID_SOFT_END_TIME = 2803;
  2216. // * TIME_WINDOW_OUTSIDE_GLOBAL_TIME_WINDOW = 2804;
  2217. // * TIME_WINDOW_START_TIME_AFTER_END_TIME = 2805;
  2218. // * TIME_WINDOW_INVALID_COST_PER_HOUR_BEFORE_SOFT_START_TIME = 2806;
  2219. // * TIME_WINDOW_INVALID_COST_PER_HOUR_AFTER_SOFT_END_TIME = 2807;
  2220. // * TIME_WINDOW_COST_BEFORE_SOFT_START_TIME_WITHOUT_SOFT_START_TIME
  2221. // = 2808;
  2222. // * TIME_WINDOW_COST_AFTER_SOFT_END_TIME_WITHOUT_SOFT_END_TIME = 2809;
  2223. // * TIME_WINDOW_SOFT_START_TIME_WITHOUT_COST_BEFORE_SOFT_START_TIME
  2224. // = 2810;
  2225. // * TIME_WINDOW_SOFT_END_TIME_WITHOUT_COST_AFTER_SOFT_END_TIME = 2811;
  2226. // * TIME_WINDOW_OVERLAPPING_ADJACENT_OR_EARLIER_THAN_PREVIOUS = 2812;
  2227. // * TIME_WINDOW_START_TIME_AFTER_SOFT_START_TIME = 2813;
  2228. // * TIME_WINDOW_SOFT_START_TIME_AFTER_END_TIME = 2814;
  2229. // * TIME_WINDOW_START_TIME_AFTER_SOFT_END_TIME = 2815;
  2230. // * TIME_WINDOW_SOFT_END_TIME_AFTER_END_TIME = 2816;
  2231. // * TIME_WINDOW_COST_BEFORE_SOFT_START_TIME_SET_AND_MULTIPLE_WINDOWS
  2232. // = 2817;
  2233. // * TIME_WINDOW_COST_AFTER_SOFT_END_TIME_SET_AND_MULTIPLE_WINDOWS = 2818;
  2234. // * TRANSITION_ATTRIBUTES_ERROR = 30;
  2235. // * TRANSITION_ATTRIBUTES_INVALID_COST = 3000;
  2236. // * TRANSITION_ATTRIBUTES_INVALID_COST_PER_KILOMETER = 3001;
  2237. // * TRANSITION_ATTRIBUTES_DUPLICATE_TAG_PAIR = 3002;
  2238. // * TRANSITION_ATTRIBUTES_DISTANCE_LIMIT_MAX_METERS_UNSUPPORTED = 3003;
  2239. // * TRANSITION_ATTRIBUTES_UNSPECIFIED_SOURCE_TAGS = 3004;
  2240. // * TRANSITION_ATTRIBUTES_CONFLICTING_SOURCE_TAGS_FIELDS = 3005;
  2241. // * TRANSITION_ATTRIBUTES_UNSPECIFIED_DESTINATION_TAGS = 3006;
  2242. // * TRANSITION_ATTRIBUTES_CONFLICTING_DESTINATION_TAGS_FIELDS = 3007;
  2243. // * TRANSITION_ATTRIBUTES_DELAY_DURATION_NEGATIVE_OR_NAN = 3008;
  2244. // * TRANSITION_ATTRIBUTES_DELAY_DURATION_EXCEEDS_GLOBAL_DURATION = 3009;
  2245. // * AMOUNT_ERROR = 31;
  2246. // * AMOUNT_NEGATIVE_VALUE = 3100;
  2247. // * LOAD_LIMIT_ERROR = 33;
  2248. // * LOAD_LIMIT_INVALID_COST_ABOVE_SOFT_MAX = 3303;
  2249. // * LOAD_LIMIT_SOFT_MAX_WITHOUT_COST_ABOVE_SOFT_MAX = 3304;
  2250. // * LOAD_LIMIT_COST_ABOVE_SOFT_MAX_WITHOUT_SOFT_MAX = 3305;
  2251. // * LOAD_LIMIT_NEGATIVE_SOFT_MAX = 3306;
  2252. // * LOAD_LIMIT_MIXED_DEMAND_TYPE = 3307;
  2253. // * LOAD_LIMIT_MAX_LOAD_NEGATIVE_VALUE = 3308;
  2254. // * LOAD_LIMIT_SOFT_MAX_ABOVE_MAX = 3309;
  2255. // * INTERVAL_ERROR = 34;
  2256. // * INTERVAL_MIN_EXCEEDS_MAX = 3401;
  2257. // * INTERVAL_NEGATIVE_MIN = 3402;
  2258. // * INTERVAL_NEGATIVE_MAX = 3403;
  2259. // * INTERVAL_MIN_EXCEEDS_CAPACITY = 3404;
  2260. // * INTERVAL_MAX_EXCEEDS_CAPACITY = 3405;
  2261. // * DISTANCE_LIMIT_ERROR = 36;
  2262. // * DISTANCE_LIMIT_INVALID_COST_AFTER_SOFT_MAX = 3601;
  2263. // * DISTANCE_LIMIT_SOFT_MAX_WITHOUT_COST_AFTER_SOFT_MAX = 3602;
  2264. // * DISTANCE_LIMIT_COST_AFTER_SOFT_MAX_WITHOUT_SOFT_MAX = 3603;
  2265. // * DISTANCE_LIMIT_NEGATIVE_MAX = 3604;
  2266. // * DISTANCE_LIMIT_NEGATIVE_SOFT_MAX = 3605;
  2267. // * DISTANCE_LIMIT_SOFT_MAX_LARGER_THAN_MAX = 3606;
  2268. // * DURATION_LIMIT_ERROR = 38;
  2269. // * DURATION_LIMIT_MAX_DURATION_NEGATIVE_OR_NAN = 3800;
  2270. // * DURATION_LIMIT_SOFT_MAX_DURATION_NEGATIVE_OR_NAN = 3801;
  2271. // * DURATION_LIMIT_INVALID_COST_PER_HOUR_AFTER_SOFT_MAX = 3802;
  2272. // * DURATION_LIMIT_SOFT_MAX_WITHOUT_COST_AFTER_SOFT_MAX = 3803;
  2273. // * DURATION_LIMIT_COST_AFTER_SOFT_MAX_WITHOUT_SOFT_MAX = 3804;
  2274. // * DURATION_LIMIT_QUADRATIC_SOFT_MAX_DURATION_NEGATIVE_OR_NAN = 3805;
  2275. // * DURATION_LIMIT_INVALID_COST_AFTER_QUADRATIC_SOFT_MAX = 3806;
  2276. // * DURATION_LIMIT_QUADRATIC_SOFT_MAX_WITHOUT_COST_PER_SQUARE_HOUR
  2277. // = 3807;
  2278. // * DURATION_LIMIT_COST_PER_SQUARE_HOUR_WITHOUT_QUADRATIC_SOFT_MAX
  2279. // = 3808;
  2280. // * DURATION_LIMIT_QUADRATIC_SOFT_MAX_WITHOUT_MAX = 3809;
  2281. // * DURATION_LIMIT_SOFT_MAX_LARGER_THAN_MAX = 3810;
  2282. // * DURATION_LIMIT_QUADRATIC_SOFT_MAX_LARGER_THAN_MAX = 3811;
  2283. // * DURATION_LIMIT_DIFF_BETWEEN_MAX_AND_QUADRATIC_SOFT_MAX_TOO_LARGE
  2284. // = 3812;
  2285. // * DURATION_LIMIT_MAX_DURATION_EXCEEDS_GLOBAL_DURATION = 3813;
  2286. // * DURATION_LIMIT_SOFT_MAX_DURATION_EXCEEDS_GLOBAL_DURATION = 3814;
  2287. // * DURATION_LIMIT_QUADRATIC_SOFT_MAX_DURATION_EXCEEDS_GLOBAL_DURATION
  2288. // = 3815;
  2289. // * SHIPMENT_ERROR = 40;
  2290. // * SHIPMENT_PD_ABSOLUTE_DETOUR_LIMIT_DURATION_NEGATIVE_OR_NAN = 4000;
  2291. // * SHIPMENT_PD_ABSOLUTE_DETOUR_LIMIT_DURATION_EXCEEDS_GLOBAL_DURATION
  2292. // = 4001;
  2293. // * SHIPMENT_PD_TIME_LIMIT_DURATION_NEGATIVE_OR_NAN = 4002;
  2294. // * SHIPMENT_PD_TIME_LIMIT_DURATION_EXCEEDS_GLOBAL_DURATION = 4003;
  2295. // * SHIPMENT_EMPTY_SHIPMENT_TYPE = 4004;
  2296. // * SHIPMENT_NO_PICKUP_NO_DELIVERY = 4005;
  2297. // * SHIPMENT_INVALID_PENALTY_COST = 4006;
  2298. // * SHIPMENT_ALLOWED_VEHICLE_INDEX_OUT_OF_BOUNDS = 4007;
  2299. // * SHIPMENT_DUPLICATE_ALLOWED_VEHICLE_INDEX = 4008;
  2300. // * SHIPMENT_INCONSISTENT_COST_FOR_VEHICLE_SIZE_WITHOUT_INDEX = 4009;
  2301. // * SHIPMENT_INCONSISTENT_COST_FOR_VEHICLE_SIZE_WITH_INDEX = 4010;
  2302. // * SHIPMENT_INVALID_COST_FOR_VEHICLE = 4011;
  2303. // * SHIPMENT_COST_FOR_VEHICLE_INDEX_OUT_OF_BOUNDS = 4012;
  2304. // * SHIPMENT_DUPLICATE_COST_FOR_VEHICLE_INDEX = 4013;
  2305. // * SHIPMENT_DETOUR_WITHOUT_PICKUP_AND_DELIVERY = 4014;
  2306. // * VEHICLE_ERROR = 42;
  2307. // * VEHICLE_EMPTY_REQUIRED_OPERATOR_TYPE = 4200;
  2308. // * VEHICLE_DUPLICATE_REQUIRED_OPERATOR_TYPE = 4201;
  2309. // * VEHICLE_NO_OPERATOR_WITH_REQUIRED_OPERATOR_TYPE = 4202;
  2310. // * VEHICLE_EMPTY_START_TAG = 4203;
  2311. // * VEHICLE_DUPLICATE_START_TAG = 4204;
  2312. // * VEHICLE_EMPTY_END_TAG = 4205;
  2313. // * VEHICLE_DUPLICATE_END_TAG = 4206;
  2314. // * VEHICLE_EXTRA_VISIT_DURATION_NEGATIVE_OR_NAN = 4207;
  2315. // * VEHICLE_EXTRA_VISIT_DURATION_EXCEEDS_GLOBAL_DURATION = 4208;
  2316. // * VEHICLE_EXTRA_VISIT_DURATION_EMPTY_KEY = 4209;
  2317. // * VEHICLE_FIRST_SHIPMENT_INDEX_OUT_OF_BOUNDS = 4210;
  2318. // * VEHICLE_FIRST_SHIPMENT_IGNORED = 4211;
  2319. // * VEHICLE_FIRST_SHIPMENT_NOT_BOUND = 4212;
  2320. // * VEHICLE_LAST_SHIPMENT_INDEX_OUT_OF_BOUNDS = 4213;
  2321. // * VEHICLE_LAST_SHIPMENT_IGNORED = 4214;
  2322. // * VEHICLE_LAST_SHIPMENT_NOT_BOUND = 4215;
  2323. // * VEHICLE_IGNORED_WITH_USED_IF_ROUTE_IS_EMPTY = 4216;
  2324. // * VEHICLE_INVALID_COST_PER_KILOMETER = 4217;
  2325. // * VEHICLE_INVALID_COST_PER_HOUR = 4218;
  2326. // * VEHICLE_INVALID_COST_PER_TRAVELED_HOUR = 4219;
  2327. // * VEHICLE_INVALID_FIXED_COST = 4220;
  2328. // * VEHICLE_INVALID_TRAVEL_DURATION_MULTIPLE = 4221;
  2329. // * VEHICLE_MINIMUM_DURATION_LONGER_THAN_DURATION_LIMIT = 4222;
  2330. // * VISIT_REQUEST_ERROR = 44;
  2331. // * VISIT_REQUEST_EMPTY_TAG = 4400;
  2332. // * VISIT_REQUEST_DUPLICATE_TAG = 4401;
  2333. // * VISIT_REQUEST_DURATION_NEGATIVE_OR_NAN = 4404;
  2334. // * VISIT_REQUEST_DURATION_EXCEEDS_GLOBAL_DURATION = 4405;
  2335. // * PRECEDENCE_ERROR = 46;
  2336. // * BREAK_ERROR = 48;
  2337. // * BREAK_RULE_EMPTY = 4800;
  2338. // * BREAK_REQUEST_UNSPECIFIED_DURATION = 4801;
  2339. // * BREAK_REQUEST_UNSPECIFIED_EARLIEST_START_TIME = 4802;
  2340. // * BREAK_REQUEST_UNSPECIFIED_LATEST_START_TIME = 4803;
  2341. // * BREAK_REQUEST_DURATION_NEGATIVE_OR_NAN = 4804; = 4804;
  2342. // * BREAK_REQUEST_LATEST_START_TIME_BEFORE_EARLIEST_START_TIME = 4805;
  2343. // * BREAK_REQUEST_EARLIEST_START_TIME_BEFORE_GLOBAL_START_TIME = 4806;
  2344. // * BREAK_REQUEST_LATEST_END_TIME_AFTER_GLOBAL_END_TIME = 4807;
  2345. // * BREAK_REQUEST_NON_SCHEDULABLE = 4808;
  2346. // * BREAK_FREQUENCY_MAX_INTER_BREAK_DURATION_NEGATIVE_OR_NAN = 4809;
  2347. // * BREAK_FREQUENCY_MIN_BREAK_DURATION_NEGATIVE_OR_NAN = 4810;
  2348. // * BREAK_FREQUENCY_MIN_BREAK_DURATION_EXCEEDS_GLOBAL_DURATION = 4811;
  2349. // * BREAK_FREQUENCY_MAX_INTER_BREAK_DURATION_EXCEEDS_GLOBAL_DURATION
  2350. // = 4812;
  2351. // * BREAK_REQUEST_DURATION_EXCEEDS_GLOBAL_DURATION = 4813;
  2352. // * BREAK_FREQUENCY_MISSING_MAX_INTER_BREAK_DURATION = 4814;
  2353. // * BREAK_FREQUENCY_MISSING_MIN_BREAK_DURATION = 4815;
  2354. // * SHIPMENT_TYPE_INCOMPATIBILITY_ERROR = 50;
  2355. // * SHIPMENT_TYPE_INCOMPATIBILITY_EMPTY_TYPE = 5001;
  2356. // * SHIPMENT_TYPE_INCOMPATIBILITY_LESS_THAN_TWO_TYPES = 5002;
  2357. // * SHIPMENT_TYPE_INCOMPATIBILITY_DUPLICATE_TYPE = 5003;
  2358. // * SHIPMENT_TYPE_INCOMPATIBILITY_INVALID_INCOMPATIBILITY_MODE = 5004;
  2359. // * SHIPMENT_TYPE_INCOMPATIBILITY_TOO_MANY_INCOMPATIBILITIES = 5005;
  2360. // * SHIPMENT_TYPE_REQUIREMENT_ERROR = 52;
  2361. // * SHIPMENT_TYPE_REQUIREMENT_NO_REQUIRED_TYPE = 52001;
  2362. // * SHIPMENT_TYPE_REQUIREMENT_NO_DEPENDENT_TYPE = 52002;
  2363. // * SHIPMENT_TYPE_REQUIREMENT_INVALID_REQUIREMENT_MODE = 52003;
  2364. // * SHIPMENT_TYPE_REQUIREMENT_TOO_MANY_REQUIREMENTS = 52004;
  2365. // * SHIPMENT_TYPE_REQUIREMENT_EMPTY_REQUIRED_TYPE = 52005;
  2366. // * SHIPMENT_TYPE_REQUIREMENT_DUPLICATE_REQUIRED_TYPE = 52006;
  2367. // * SHIPMENT_TYPE_REQUIREMENT_NO_REQUIRED_TYPE_FOUND = 52007;
  2368. // * SHIPMENT_TYPE_REQUIREMENT_EMPTY_DEPENDENT_TYPE = 52008;
  2369. // * SHIPMENT_TYPE_REQUIREMENT_DUPLICATE_DEPENDENT_TYPE = 52009;
  2370. // * SHIPMENT_TYPE_REQUIREMENT_SELF_DEPENDENT_TYPE = 52010;
  2371. // * SHIPMENT_TYPE_REQUIREMENT_GRAPH_HAS_CYCLES = 52011;
  2372. // * VEHICLE_OPERATOR_ERROR = 54;
  2373. // * VEHICLE_OPERATOR_EMPTY_TYPE = 5400;
  2374. // * VEHICLE_OPERATOR_MULTIPLE_START_TIME_WINDOWS = 5401;
  2375. // * VEHICLE_OPERATOR_SOFT_START_TIME_WINDOW = 5402;
  2376. // * VEHICLE_OPERATOR_MULTIPLE_END_TIME_WINDOWS = 5403;
  2377. // * VEHICLE_OPERATOR_SOFT_END_TIME_WINDOW = 5404;
  2378. // * DURATION_SECONDS_MATRIX_ERROR = 56;
  2379. // * DURATION_SECONDS_MATRIX_DURATION_NEGATIVE_OR_NAN = 5600;
  2380. // * DURATION_SECONDS_MATRIX_DURATION_EXCEEDS_GLOBAL_DURATION = 5601;
  2381. // * GRAPH_ARC_ERROR = 58;
  2382. // * GRAPH_ARC_DURATION_NEGATIVE_OR_NAN = 5800;
  2383. // * GRAPH_ARC_DURATION_EXCEEDS_GLOBAL_DURATION = 5801;
  2384. int32 code = 1;
  2385. // The error display name.
  2386. string display_name = 2;
  2387. // An error context may involve 0, 1 (most of the time) or more fields. For
  2388. // example, referring to vehicle #4 and shipment #2's first pickup can be
  2389. // done as follows:
  2390. // ```
  2391. // fields { name: "vehicles" index: 4}
  2392. // fields { name: "shipments" index: 2 sub_field {name: "pickups" index: 0} }
  2393. // ```
  2394. // Note, however, that the cardinality of `fields` should not change for a
  2395. // given error code.
  2396. repeated FieldReference fields = 3;
  2397. // Human-readable string describing the error. There is a 1:1 mapping
  2398. // between `code` and `error_message` (when code != "UNSPECIFIED").
  2399. //
  2400. // *STABILITY*: Not stable: the error message associated to a given `code` may
  2401. // change (hopefully to clarify it) over time. Please rely on the
  2402. // `display_name` and `code` instead.
  2403. string error_message = 4;
  2404. // May contain the value(s) of the field(s). This is not always available. You
  2405. // should absolutely not rely on it and use it only for manual model
  2406. // debugging.
  2407. string offending_values = 5;
  2408. }